Generate XSD For Existing Classes

If you’re sharing XML between applications, you need to communicate and agree upon the format of the XML. A common way to do this is by using XSD files. Microsoft’s XSD tool (XSD.exe) allows you to generate an XSD for an existing class quickly and easily. (I recommend using a Visual Studio Command Prompt. This is not necessary, but it saves you from having to browse to the XSD tool’s directory or worry about environment variables.)

The usage to do this is as follows:

xsd {file.dll | file.exe} [/outputdir:directory] [/type:typename [...]][/parameters:file.xml]

Typically, I’ll either generate an XSD for an entire DLL or a single class. If you choose to do a single class, it will also include classes that are dependencies.

xsd myassembly.dll
xsd myassembly.dll /type:myclass

Read more about the XSD tool at MSDN:
http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.80).aspx.

Advertisements

Windows Workflow 4: Creating a Simple Custom Activity

The Windows Workflow Foundation project that I’m working on relies on my ability to create a library of custom activities that can be used together to handle many different customer scenarios. Creating a simple custom activity is a very easy and straightforward task with WF4. This post will walk you through the steps of creating a custom send-email activity.

The first thing you’ll need to do is create a new class that inherits from NativeActivity. (Note that NativeActivity is not your only option–check out this post for an overview of the different choices.) NativeActivity is an abstract class that requires us to implement an Execute method. This is the method that runs when the activity executes.

public sealed class EmailActivity : NativeActivity
{
    protected override void Execute(NativeActivityContext context)
    {
        throw new NotImplementedException();
    }
}

We’ll need some additional information in order to send an email, and we can use input arguments to get what we need. To add an input argument, create a public property of type InArgument<T>. Here are my input properties. Notice that I’ve decorated some of them with the [RequiredArgument] attribute to indicate that they are required. Output arguments can be added in a similar fashion by using OutArgument<T>, though we do not need any for this example.

[RequiredArgument]
public InArgument<string> Host { get; set; }

[RequiredArgument]
public InArgument<string> Sender { get; set; }

[RequiredArgument]
public InArgument<string> Recipients { get; set; }

public InArgument<string> Subject { get; set; }

public InArgument<string> Body { get; set; }

Now that we have all the information we need, we just need to implement the Execute method to send an email. Once again, it’s very simple.

protected override void Execute(NativeActivityContext context)
{
    // create the email message
    var mailMessage = new MailMessage();
    mailMessage.From = new MailAddress(Sender.Get(context));
    mailMessage.To.Add(new MailAddress(Recipients.Get(context)));
    mailMessage.Subject = Subject.Get(context);
    mailMessage.Body = Body.Get(context);

    // send the message
    var smtpClient = new SmtpClient(Host.Get(context));
    smtpClient.Send(mailMessage);
}

This activity can now be added to your workflow XAML through the designer or any text editor. In the example below, I have bound the Body property to a variable named StatusText that will be set in an earlier activity.

<my:EmailActivity
  Host="mail.mydomain.com"
  Sender="myworkflow@mydomain.com"
  Recipients="someuser@mydomain.com"
  Subject="Workflow Status Update"
  Body="[StatusText]" />

Here is the complete class:

public sealed class EmailActivity : NativeActivity
{
    [RequiredArgument]
    public InArgument<string> Host { get; set; }

    [RequiredArgument]
    public InArgument<string> Sender { get; set; }

    [RequiredArgument]
    public InArgument<string> Recipients { get; set; }

    public InArgument<string> Subject { get; set; }

    public InArgument<string> Body { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
        // create the email message
        var mailMessage = new MailMessage();
        mailMessage.From = new MailAddress(Sender.Get(context));
        mailMessage.To.Add(new MailAddress(Recipients.Get(context)));
        mailMessage.Subject = Subject.Get(context);
        mailMessage.Body = Body.Get(context);

        // send the message
        var smtpClient = new SmtpClient(Host.Get(context));
        smtpClient.Send(mailMessage);
    }
}

Windows Workflow 4: Dynamically Load Workflows

I’m starting a new project where I plan to use Windows Workflow Foundation to load custom jobs from external XML files like plug-ins. In order for this to work, I’ll have a sub-directory that my application watches. If files are found, they will be loaded and executed.

The reason I want to do this is because Windows Workflow Foundation 4 makes it easy to keep the workflows as human-readable XML files that can be edited by technical-but-not-developer users. This allows for easy, efficient customization of workflows. The processes we have now require developer interaction for any customization or modification since everything is compiled into DLLs making our development team an unnecessary bottleneck for warranty and enhancement.

Over the next days and weeks, I’ll be publishing a number of posts that demonstrate small nuggets of WF4 functionality. I’ve been impressed with what I’ve been able to accomplish in just a few days of fooling around, so this I’m very excited about this endeavor!

I’m keeping it short and simple with this post: loading and running an XML (XAML) workflow from a file at runtime. This very powerful functionality can be accomplished in a single line of code:

WorkflowInvoker.Invoke(ActivityXamlServices.Load("HelloWorld.xml"));

One of my main goals is encapsulating all of my functionality in human-readable XML, so I also wanted to provide the contents of my HelloWorld.xml file. This workflow is unimpressive and simply writes “Hello, world!” to the console, but here it is, nonetheless:

<Activity xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <WriteLine Text="Hello, world!" />
</Activity>

Redirect Console Output in C#

Those of you that know me know that I love a good console application. I use them all the time for samples and prototypes. Sometimes it’s nice to capture the output from a console application to share with others.

It’s remarkably simple to accomplish this with the .NET Framework. There is a static method Console.SetOut that accepts a TextWriter. Redirecting output from your console application is as simple as creating a TextWriter and calling that method.

Here’s a quick example (taken directly from MSDN):

Console.WriteLine("Hello World");
FileStream fs = new FileStream("Test.txt", FileMode.Create);
// First, save the standard output.
TextWriter tmp = Console.Out;
StreamWriter sw = new StreamWriter(fs);
Console.SetOut(sw);
Console.WriteLine("Hello file");
Console.SetOut(tmp);
Console.WriteLine("Hello World");
sw.Close();

XSL Transformations in C#

In Visual Studio 2005 (yea–this happened a few years ago), Microsoft redesigned the architecture of their XSL transformations. It wasn’t difficult to execute a simple transformation before, but it’s downright ridiculous now.

Here’s a complete example of executing a simple XSL transformation:

using System.Xml.Xsl;

namespace Xml.XslTransformation
{
    class Program
    {
        static void Main(string[] args)
        {
            var prog = new Program();
            prog.Run();
        }

        public void Run()
        {
            var xslt = new XslCompiledTransform();
            xslt.Load("mapping.xslt");
            xslt.Transform("sample.xml", "output.xml");
        }
    }
}

EmitDefaultValue and the DataContractSerializer

Often times when serializing an object to XML, you may want to include empty elements with their default values. This is the default behavior of the .NET Framework’s DataContractSerializer, but it can be toggled by using the EmitDefaultValue property in the DataMember attribute on a class’s properties. EmitDefaultValue has a default value of true, meaning it will include empty elements with their default value. Setting this property to false causes empty elements to be excluded.

Here’s a complete example:

namespace Serialization.EmitDefaultValue
{
    [DataContract]
    public class Human
    {
        [DataMember]
        public string Name { get; set; }
    }

    [DataContract]
    public class HumanNoDefault
    {
        [DataMember(EmitDefaultValue = false)]
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var prog = new Program();
            prog.Run();
        }

        public void Run()
        {
            SerializeToConsole<Human>();
            SerializeToConsole<HumanNoDefault>();

            Console.ReadLine();
        }

        public void SerializeToConsole<T>() where T : new()
        {
            using (var ms = new MemoryStream())
            {
                var h = new T();
                var serializer = new DataContractSerializer(typeof(T));
                serializer.WriteObject(ms, h);
                ms.Seek(0, SeekOrigin.Begin);
                var sr = new StreamReader(ms);
                Console.WriteLine("{0}:{1}{2}{1}", typeof(T).Name, Environment.NewLine, sr.ReadToEnd());
            }
        }
    }
}

And the output (note that the Name element is excluded in the second XML):

Human:
<Human xmlns="http://schemas.datacontract.org/2004/07/Serialization.EmitDefaultValue" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Name i:nil="true"/></Human>

HumanNoDefault:
<HumanNoDefault xmlns="http://schemas.datacontract.org/2004/07/Serialization.EmitDefaultValue" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>

Verify Function Arguments Using Constraints in Rhino Mocks

Verifying arguments passed into a mocked or stubbed method can help you write more specific, robust unit tests. This is easily accomplished with Rhino Mocks by using Constraints.

As an example, let’s write a test for the function MyClass.MyMethod in the code below:

public interface IMyDependency
{
    void DependencyMethod(MyResult myResult);
}

public class MyResult
{
    public int Code;
}

public class MyClass
{
    public IMyDependency MyDependency { get; set; }

    public MyClass(IMyDependency myDependency)
    {
        MyDependency = myDependency;
    }

    public void MyMethod(string input)
    {
        switch (input)
        {
            case "A":
                MyDependency.DependencyMethod(
                    new MyResult { Code = 1 });
                break;
            case "B":
                MyDependency.DependencyMethod(
                    new MyResult { Code = 2 });
                break;
            default:
                break;
        }
    }
}

The first thing we need to do is create a mock IMyDependency and verify that its DependencyMethod is called, so let’s do that:

[TestMethod]
public void MyMethodTest()
{
    // Arrange
    var mockMyDependency = MockRepository.GenerateMock();
    var target = new MyClass(mockMyDependency);

    mockMyDependency.Expect(
        x => x.DependencyMethod(Arg<MyResult>.Is.Anything));

    const string input = "A";

    // Act
    target.MyMethod(input);

    // Assert
    mockMyDependency.VerifyAllExpectations();
}

This test passes, but how do we know the argument with the correct value was used? We can modify our mock object’s Expect call to use argument constraints to do this!

mockMyDependency.Expect(
    x => x.DependencyMethod(Arg<MyResult>.Matches(arg => arg.Code.Equals(1))));

Now my test only passes when the mock is called with an argument that matches the specified criteria. This is obviously a very basic example, but the fact that you can pass a delegate or derive a custom class from Rhino Mocks’s AbstractConstraint class makes this a very powerful feature.