XAML Code Generation Markup Language

I have a very simple working prototype of the XAML Code Generator that I was discussing in my last post. It turns out that it’s totally possible! So for example if you have XAML that looks like this:

<test:Parent xmlns=”clr-namespace:Xcgml;assembly=Xcgml”

     xmlns:test=”clr-namespace:Xcgml.Testing.Mock;assembly=Xcgml.Testing” >

     <test:Child Data=”{Binding}” />

</test:Parent>

What we have here are two classes that inherit from GeneratorElement (which inherits from DependencyObject) and one other class called Binding that inherits from MarkupExtension. After running this XAML through the XamlReader, you end up with deserialized objects.

public static GeneratorElement Load(string xaml)

{

    using (TextReader reader = new StringReader(xaml))

    {

        using (XmlReader xmlReader = XmlReader.Create(reader))

        {

            ParserContext context = new ParserContext();

            context.XmlLang = “xcgml”;

 

            return (GeneratorElement)System.Windows.Markup.XamlReader.Load(xmlReader);

        }

    }    

}

The interesting thing is the binding. It turns out that there is no automatic system for resolving bindings like I had hoped but fortunately it’s possible to implement your own. It seems like a lot of what we get seemingly for free in WPF sits on top of the FrameworkElement class. The framework element class is not available for this scenario; I must implement my own elements on top of DependencyObject. However it wasn’t very hard to figure out how to propagate the DataContext and how to refresh values based on bindings. Here is an example unit test:

[TestMethod]

public void Simple1()

{

    Parent element = XamlReader.Load(Resources.Simple1) as Parent;

    Assert.IsNotNull(element);

    Assert.IsNotNull(element.Content);

    Assert.IsInstanceOfType(element.Content, typeof(Child));

 

    string expected = “success”;

    element.DataContext = expected;

    string actual = (element.Content as Child).Data;

 

    Assert.AreEqual(expected, actual);

}

Notice when I set the element.DataContext the child’s Data property will change because of the binding specified! I am planning on adding these features soon:

<!–[if !supportLists]–>·         <!–[endif]–>StaticResource binding – so you can bind to values in resources

<!–[if !supportLists]–>·         <!–[endif]–>Templates – so you can customize standard objects

<!–[if !supportLists]–>·         <!–[endif]–>ItemsControl – so you can have multiple nested controls

<!–[if !supportLists]–>·         <!–[endif]–>Repeat control

<!–[if !supportLists]–>·         <!–[endif]–>If control

 

Download the Source

<!–[if !supportLists]–>·         <!–[endif]–>Xcgml-20080731.zip (17.2 KB)

XAML View Engine

I just had an interesting idea and wanted to blog it down before forgetting since I can’t really spend time investigating it now.

Well I’ve been working with NVelocity and now Spark to use as my view engine for template generation. I’m very happy with Spark right now (since it actually works) and I have been generating templates like a fool the last couple days. I think I might have a preview release of NBusiness 3 out for testing sometime soon.

That being said there is definitely still something missing. It works… it’s a heck of a lot better than NVelocity but it’s not quite perfect. I was just mentioning this to a friend and suddenly had a jolt of inspiration. I had the idea that you could, quite possibly, declare your entire template in XAML . Your XAML syntax could support binding and you could have looping and conditional controls right in it. This would allow you to declaratively define code in arbitrary languages. Pretty interesting… here is a little snippet of what I was envisioning:

<Class Attributes=”Public, Abstract” Base=”BusinessBase” Name=”{Binding Name}”>

   <Repeat Collection=”{Binding Fields}”>

      <Field Name=”field” Attributes=”Private” Type=”{Binding Path=Type}” Name=”{Binding Path=Name, Converter=FIeldNameConverter}” />

      <Property Attributes=”Public” Type={Binding Path=Type}” Name={Binding Path=Name}”>

         <Property.Getter><Return Expression=”{Binding RelativeSource=field}” /></Property.Getter>

      </Property>

   </Repeat>

  

</Class>

Honestly, I’m thinking that all I have to do is create these objects which would inherit from DependencyObject and the XAML serializer will do the rest… I doubt it would be that simple but I may have to try it out later tonight.

The thing is, once you have this template into a DOM you could then run it through some sort of Conversion process to create CodeDom objects which would produce code for any arbitrary language! The trick would be to make it flexible enough to support conversion to things like HTML or whatever. Wow, this could be interesting.

Boo Shirts

I think I am going to order some boo shirts, I want one for myself and I’ll probably give a few away at my upcoming boo presentations so I’ll order in bulk. Here’s the shirt:

If anyone wants one let me know because I can get them a little bit cheaper since there is a discount for bulk ordering. Send me an email directly with the following information:

  • Your name
  • Your mailing address
  • Shirt size

We’ll work out payments be it through pay pal or some-other means. The price of the shirt will be exactly what I paid to have them made plus shipping. The more people who want one the cheaper they will be. If you’re willing to pay for international shipping than I’m willing to send it!

[EDIT] The cafe press widget I was linking to was broken so I just swapped it out with a picture of the actual shirt. See representing boo for more. I can still order more if you want.

Spark view engine

If you’re interested in the new Microsoft MVC framework but you’re a little skeptical about going back to a classic ASP Tag Soup rendering system, you should check out the Spark View Engine.

It has a very interesting way of allowing you to write your view with some simple string replacements and also specialized tags that appear to be actual HTML. The general idea is basically the same but visual appeal is quite a bit better.

Here is an example:

<var names=“new [] {‘alpha’, ‘beta’, ‘gamma’}”/>

<for each=“var name in names”>

  <test if=“name == ‘beta'”>

    <p>beta is my favorite.</p>

    <else/>

    <p>${name} is okay too I suppose.

  </test>

</for>

 In this case your “foreach” loop appears to actually be part of the html. The code inside of the each attribute is compiled as C#.  The system it uses is pretty straightforward and easy to understand which gives me a lot of confidence in it already.

I have been having problems getting NVelocity to work properly so I am going to try to use Spark as the default NBusiness code generation tool. We’ll see how intuitive it is to have this pseudo-html markup inside of code but I suspect this tool will work much better for NBusiness.

ESharp Validation Rule Breakthrough

After a late night of hacking I have finally got an end to end transformation of E# validation rules into CSLA code that compiles. I am using the NVelocity code generator I created to do this, here is the example entity I have defined:

using NBusiness.Frameworks.Csla.Templates;

using Csla.Validation.CommonRules;

 

family Test

{

      entity A as EditableRoot

      {

            field auto id int aid;

            field nullable string data;

            field nullable double value;

           

            validate data StringMaxLength { MaxLength : 10 };

      }

}

 

After running this through the compiler here is the code that it generated:

using System;

using Csla;

using Csla.Validation;

using System.Collections.Generic;

 

namespace Test

{

      [Serializable]

      public partial class A : BusinessBase<A>

      {

            #region Properties

            private static PropertyInfo<int> aidProperty = RegisterProperty<int>(

                  typeof(A),

                  new PropertyInfo<int>(“aid”));

            /// <summary>

            /// aid property

            /// </summary>

            public int aid

            {

                  get { return GetProperty<int>(aidProperty); }

            }

            private static PropertyInfo<string> dataProperty = RegisterProperty<string>(

                  typeof(A),

                  new PropertyInfo<string>(“data”));

            /// <summary>

            /// data property

            /// </summary>

            public string data

            {

                  get { return GetProperty<string>(dataProperty); }

                  set { SetProperty<string>(dataProperty, value); }

            }

            private static PropertyInfo<System.Nullable<double>> valueProperty = RegisterProperty<System.Nullable<double>>(

                  typeof(A),

                  new PropertyInfo<System.Nullable<double>>(“value”));

            /// <summary>

            /// value property

            /// </summary>

            public System.Nullable<double> value

            {

                  get { return GetProperty<System.Nullable<double>>(valueProperty); }

                  set { SetProperty<System.Nullable<double>>(valueProperty, value); }

            }

            #endregion

 

            #region Relationships

            #endregion

           

            #region Validation

            protected override void AddBusinessRules()

            {

                  Dictionary<string, object> dataArgs = new Dictionary<string, object>();

                  dataArgs.Add(“MaxLength”, 10);

                  ValidationRules.AddRule(

                        Csla.Validation.CommonRules.StringMaxLength,

                        new DecoratedRuleArgs(dataProperty, dataArgs));

            }

            #endregion

      }

}

(You can see the power of a DSL simply by looking at how many more lines of code it takes to represent the same thing in a lower level language!)

It has taken me a loooong time to get to this point and I think it’s all downhill from here. Trying to find out how to discover validation / access / authorization rules from arbitrary business object frameworks turns out to be a terribly difficult thing to do. There is lots of room for improvement but I think I have the basics down for now. This should allow me to generate code for CSLA and NBusiness frameworks at least and perhaps a couple of others without too much work.

Next up is largely a process of cleaning up code (I have been hacking on things a lot recently), fixing up unit tests and fleshing out CSLA templates for each major stereotype (I love that word in a software context!). What a relief!

Unit Testing Asynchronous Code in Silverlight

My current job is a very enjoyable one. I have the pleasure of working for Rocky Lhotka on CSLA 3.6 and CSLA Light, more specifically CSLA Light but the two definitely bleed together.

CSLA Light is a project where we are trying to create a version of CSLA that will run on Silverlight. If you’re interested in hearing more details about this you should check out Rocky’s blog since it is the most up to date authority on CSLA development progress.

One of the problems we ran into right away was the ability to unit test our Silverlight code. Unit testing on Silverlight presents a number of limitations that are not present in a standard .net application. We initially tried using the unit test framework provided by Microsoft but found it impossible to test anything with a WCF service call in it due to threading.

To help illustrate the problem consider the following test:

[TestClass]

public class TestExample

{

    [TestMethod]

    public void Example()

    {

        ManualResetEvent mre = new ManualResetEvent(false);

        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += (o, e) =>

        {

            // Do some processing…

        };

        worker.RunWorkerCompleted += (o, e) =>

        {

            mre.Set();

        };

        worker.RunWorkerAsync();

 

        mre.WaitOne();

    }

}

This test simulates a unit of work that is performed asynchronously. If you run this test in Silverlight what will happen? Also, suppose in your DoWork method there is bug and an Exception is thrown, what will happen? I’ll get back to this in a moment.

One of the features of CSLA is something called the “Data Portal” which is a concept that has been preserved in CSLA Light with only some slight differences, primarily all network calls in Silverlight must be done asynchronously. The Data Portal is the mechanism your CSLA business objects must use to transfer data across network separated application tiers. In CSLA 3.6 an asynchronous Data Portal has been created to provide parity with Silverlight, not to mention the fact that it’s just plain cool.

One interesting thing to know about Silverlight is that whenever you use WCF to make a network call it will dispatch that call onto the UI thread. I believe this is actually a limition of the browser rather than Silverlight itself, it must be piggy backing on top of the browser XmlHttpRequest functionality and therefore suffers from the same limitations.

This is a major problem for the Silverlight MSTest framework! Since your test is running on the UI thread if your test tries to make a WCF call it will need to be dispatched to the UI to work and you will end up with a deadlock. The above test will not work in Silverlight because we have used a ManualResetEvent to hold the UI thread since it too will dispatch to the UI thread.

So to respond to this we came up with a light weight unit testing framework that will allow you to easily test asynchronous code in Silverlight and to accompany NUnit or MSTest in .NET. The project is on Codeplex and it is called Unit Driven. It is designed to allow you to easily test asynchronous code in both Silverlight and .NET. In fact, in CSLA the test code we are writing is identical for both CSLA and CSLA Light despite the various differences in the environments. Here is an example of how you would write the previous test to address all of the questions I posed using Unit Driven:

[TestClass]

public class TestExample : TestBase

{

    [TestMethod]

    public void Example()

    {

        UnitTestContext context = GetContext();

        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += (o, e) =>

        {

            // Do some processing…

        };

        worker.RunWorkerCompleted += (o, e) =>

        {

        };

        worker.RunWorkerAsync();

 

        context.Complete();

    }

}

The subtle differences in this approach are simply that you’re using the UnitTestContext object to block the thread, or not, for you depending on the framework your test is running in as well as having an AsyncAsserter to manage getting exceptions back to the test thread for you.

In the first example you would end up in a deadlock in Silverlight and if your DoWork method threw an exception in either framework it would be interpreted as an unhandled exception and would cause your test to hang. With UnitDriven we are able to manage this easily by using an Assert.Try( … )

[TestMethod]

[ExpectedException(typeof(InvalidOperationException))]

public void ExpectedExceptionExample()

{

    UnitTestContext context = GetContext();

    BackgroundWorker worker = new BackgroundWorker();

    worker.RunWorkerCompleted += (o, e) =>

    {

        // catches exception here and passes to the context.

        context.Assert.Try(() =>

        {

            throw new InvalidOperationException();

        });

        context.Assert.Fail();

    };

    worker.RunWorkerAsync();

 

    // When the context is triggered it will find the

    // exception and re-throw it in .NET

    // and simply pass it back in Silverlight.

    context.Complete();

}

For some working examples check out our AsyncTests.cs on codeplex.

Happy Testing!

NVelocity Code Generation Tool for NBusiness

I’ve really been struggling with how to improve creating templates for NBusiness 3 so that it is much easier than it is now. I have been delayed by the prospect of actually creating any more templates with the CodeDom. It is just too painful and ugly.

On one hand I really want templates to be classes because this allows me to search for them easily, they are either in the same assembly or in a referenced assembly. It also allows me to easily gather meta-data about templates (attributes) and actually run the templates. It also allows for the template developer to generate code however they way, it’s very powerful. There also does not need to be some special path that you store templates in and there does not need to be a relative path specified in the entity. It’s a very light-weight and powerful way to do templates.
Unfortunately the problem with this approach is that your templates are probably going to end up being done with the CodeDom, which as you probably know is a royal pain in the butt. If you try to use a template engine such as NVelocity then you’re stuck taking care of the path issues yourself, which is ok but is also sort of annoying.
Well last night I finally figured out a great solution to this problem. I have decided to include an NBusinessTemplateCodeGenerator Custom Tool to the visual studio integration project. This custom tool will generate for you a template class, based on a template file it is applied to in your solution. Then your entities can reference that template and will use NVelocity to do the generation. I plan on making it extensible somehow so other template tools (such as codesmith?) could be used. Here are some screenshots of a working prototype.
So in this example my simple NVelocity template has the following code:

using System;
 
namespace $entity.Namespace
{
      public partial class $entity.Name
      {
#foreach($field in $entity.Fields)
            public $field.TypeName $field.Name { get; set; }
#end
      }
}
The .nbt (NBusiness Template) file will create a Template class such as this:

[NBusiness.Templates.CodeTemplateAttribute()]
public class TestTemplate : NBusiness.Templates.TemplateBase {
    protected override NBusiness.CodeDom.Compiler.EntityFile Compile(NBusiness.CodeDom.Entity entity, NBusiness.CodeDom.Compiler.EntityCompileParameters parameters) {
        NBusiness.Templates.ICodeGeneratorEngine engine = NBusiness.Templates.CodeGeneratorEngine.GetEngine();
        string template = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(@”IyoNCiAgICBTaW1wbGUgRW50aXR5SW5mbyBDb…you get the idea”));
        byte[] generated = engine.Generate(entity, template, parameters);
        return new NBusiness.CodeDom.Compiler.EntityFile(entity.Name, generated);
    }
}
…Which is ugly, which is why this tool was created. It will convert your template code into a base64 string which will be converted back into code before getting passed into the NVelocity engine and merged with the incoming entity. This class will now be accessible by entities in the same project or referencing projects.
Your entity file might look like this:

using ClassLibrary1;
 
family Test
{
      entity A as TestTemplate
      {
            field auto id int aid;
            field nullable string data;
            field nullable double value;
      }
}
Which when run through the TestTemplate will produce code that looks like this:

using System;
 
namespace Test
{
      public partial class A
      {
            public int aid { get; set; }
            public string data { get; set; }
            public System.Nullable<double> value { get; set; }
      }
}
So all you have to do to get NVelocity working with NBusiness entities and models will be to add a .nbt file to your project which (if done through the Add New Item dialog) will have the Custom Tool NBusinessTemplateCodeGenerator applied to it. Then author away!
I will be using this system to author the core templates that come with NBusiness from now on.