Saturday, May 12, 2007

Using C# 3.0's Extension Methods to generate MCML from Reference types

Other versions of the article:

HTM Version

XPS Version

C# 3.0 features Extension Methods, static methods which will let you extend the functionality of
existing types, without having to sub-class the type or modifying the original source code. This article discusses how to use this feature to generate Media Center Markup Language (MCML) in a re-usable and extensible way.


The basics: Value Types


Let’s start by creating a very basic extension method:


public static String ToMcml(this string target, string name) {

return String.Format("<cor:String Name=\"{0}\" String=\"{1}\"/>",

name, target);

}


Notice the keyword “this” in front of type “string” which let’s the compiler know which type is going to be extended by this method. In this case adding a reference to the namespace where this method is implemented will add the “ToMcml” method to any instance of type string.


This lets the developer generate the MCML markup for any string in the following forms:



String mcmlText = String.Empty;

Console.WriteLine(mcmlText.ToMcml("McmlProperty"));

Console.WriteLine("String
Value"
.ToMcml("AnotherMcmlProperty");


After this is ready, adding overloads for additional value types is a pretty straight-forward process.


Converting Reference Types to Property Sets


Converting Reference Types is not as easy and will require some additional code and the use of Reflection. If we want these extension methods to be really reusable we want them to be able to act over any type and not just a specific one. This means we have to resort to extending type “object”, base of any other type in the framework, and re-use any other extension method we had already implemented to convert value types, in the following way:



public static String ToPropertySet(this object target, String name) {

String result = String.Empty;

Type type = target.GetType();

result += String.Format("\n <!-- Main Type Name: {0} -->",
type.Name);

PropertyInfo[] propertyInfoArray = type.GetProperties();

result += String.Format("\n <!-- Field count: {0} -->",

propertyInfoArray.Length);

foreach (PropertyInfo propertyInfo in propertyInfoArray) {

result +=

String.Format("\n <!-- {0} -->",

propertyInfo.PropertyType.Name);

switch (propertyInfo.PropertyType.Name){

case "String":

result += "\n " +

((String)propertyInfo.GetValue(target,null))

.ToMcml(propertyInfo.Name);

break;

}

}

result = String.Format("\n<Entries>{0}\n</Entries>",
result);

if (name != null) {

return result = String.Format(

"<PropertySet Name=\"{1}\">{0}\n</PropertySet>",

result,

name);

} else {

return result = String.Format(

"<PropertySet>{0}\n</PropertySet>",

result);

}

}

Although up to this point this method will only convert properties of String type, it is not a problem to add additional conversions methods and cases for value types.


It is also possible to change the “String.Format” method calls by proper XML handling techniques; however this is beyond the purposes of this article.


The result: MCML


Once we have a reference to the namespace where these methods are implemented, we can apply them the following way:


Declaring a new reference type (the C# 3.0 way):



public class TestType {

public string Name { get; set; }

public string ID { get; set; }

public string VideoUri { get; set; }

}


Instantiating, initializing and calling the extension method:


TestType target = new TestType();

string name = "TestPropertySetName";

target.ID = "{5B1BFC9A-9BFE-42f8-9655-B736496CAA4B}";

target.Name = "TestName";

target.VideoUri = "http://www.test.com/";

Console.WriteLine(target.ToPropertySet(name));


Following the output in the console:


<PropertySet Name="TestPropertySetName">

<Entries>

<!-- Main Type Name: TestType -->

<!-- Field count: 3 -->

<!-- String -->

<cor:String Name="Name" String="TestName"/>

<!-- String -->

<cor:String Name="ID" String="{5B1BFC9A-9BFE-42f8-9655-B736496CAA4B}"/>

<!-- String -->

<cor:String Name="VideoUri" String="http://www.test.com/"/>

</Entries>

</PropertySet>


This is a definitely useful technique for web-hosted MCML applications which backend is implemented using version 3.5 of the .NET Framework. Although this is not likely to happen any time soon, I sincerely cannot wait for it J

Monday, May 7, 2007

Extended MCML Schema

If you have developed user interfaces for Media Center in Windows Vista using MCML and Visual Studio 2005 you probably have noticed that even with the corresponding SDK installed "Intellisense" ability is lost once you have gone too deep into the intricacies of MCML syntax. This also provokes several sections are marked as invalid by the syntax verifier even when they run perfectly when tested with the rendering engine.

During the past weekend I started researching for the cause of this issue and how to solve it. I already knew XML-based files were verified using an XML schema installed as an add-on to Visual Studio, however, I didn't know where those files live and was somewhat uncertain what the actual structure of the file would be.

After a couple of Internet searches I found out the folder:

%ProgramFiles%\Microsoft Visual Studio 8\Xml\Schemas

A quick look on it took me to the file "mcml2006.xsd" which is editable from Visual Studio.

After several tries I was able to introduce the first change, which was adding an "Animation" as a valid entry in a "PropertySet". From there everything else was relatively simple and I ended up adding several other entries that I knew were valid but not accepted by the syntax verifier or had Intellisense support.

The result can be downloaded from here:

http://www.murven.com/archive/mcml2006.zip

For installation simply uncompress and copy to:

%ProgramFiles%\Microsoft Visual Studio 8\Xml\Schemas

Please send your comments and questions and let me know if I left any important entry out of it.

*****UPDATE*******

After writing markup for several days I noticed there were several other missing entries (Including the requested ). You can download the new update from here:

http://www.murven.com/archive/mcml2006.zip

English Blog

After some thinking I decided it was time to start an English Blog.

I have been maintaining my
Spanish blog for a couple of years now, but with the increasing need of publishing content for the English-speaking readers, maybe I delayed this a bit longer than I should.


I also decided this was going to be a tech-only blog; after all, almost everyone interested in my personal stuff are either Spanish or Portuguese speakers and therefore I will continue to post personal stuff only there. I will also leave my posts for hobbie-related stuff out of this blog, meaning you won't see anything on photography, numismatics or anime around here.

However, as there is a noticeable lack of good tech-related material in Spanish in certain areas I am related with, I will do my best post for both languages on those topics.

I hope this will become a good source of information in topics like Media Center, Windows Vista, .NET Framework 3.0, etc.

Thanks for your visit and please feel free to leave your comments.