Archive

Posts Tagged ‘WF’

Books, books, books …

May 16th, 2008 stiiifff No comments

My house will look like a bookstore soon :D I've been reading & ordering too many books lately … lol

(Guess it's gonna slow down soon, our most awaited friend 'Sun' is finally coming back to Belgium, my lovely rainy home-country. No wonder why beers are so popular here.)

In case you missed them, here is a quick list of some highly recommended books:

  • Domain-Specific Development with Visual Studio DSL Tools: Good read to discover Domain-Specific Development with Visual Studio.
  • Programming WCF Services: another masterpiece from Juval Lowy. Cautious: This is a tough read, not an introductory book. But it will surely help you appreciate the design of WCF in all its glory (am I exaggerating ?). Also, if you have the opportunity to attend Juval's stellar presentation 'Beyond the endpoints', don't hesitate 1 second: it was an enlightening experience.
  • Patterns of enterprise application architecture: Not new, but you'll find yourself often coming back to it as it provides so much insight about the design of so-called 'enterprise applications'. Don't call yourself senior .net developer or architect if you haven't read it yet :)
  • Java persistence with Hibernate: Yeah, I said 'Java' & 'Hibernate' … why ? because if you wanna know (mostly) everything about persistence with an ORM tool, that's the book. You can then learn any other ORM in 5 minutes.

Other books as recommendable as the previous, that I have at home but haven't read yet (and will read asap lol):

  • Release It!: Just received it today, and by looking at the back cover and table of contents, I wish I had read it several years ago. One advice: Read It! ;) That's what I'm going to do …
  • Visual Studio Extensibility: The perfect companion for Domain-Specific Development with Visual Studio if you want to create DSL that are highly integrated into VS. I'd like to know more about that Visual Studio 2008 Shell also … looks promising.
  • Essential Windows Workflow Foundation: Wanna gain more insight about the design of WF? Everything's in here.
  • Framework Design Guidelines – Conventions, Idioms, and Patterns for Reusable .NET Libraries: Do I have to say that it's a must-read for any framework-developer ? Shamefully, I haven't read it yet. Gonna fix that.

Well … gotta go, I have 4 books to read ;)

Categories: Belgium, DSL, ORM, Patterns, WCF, WF Tags: , , , ,

Dependency Injection on your WCF & WF services

April 28th, 2008 stiiifff No comments

You are using an Inversion of Control container for your application components and you are exposing some services through WCF. Wouldn’t it be nice if you could host those services in your container and benefit from Dependency Injection ?

Well, that’s easy if you’re using Castle Project‘s Windsor container: just register the WcfIntegration facility and you’re on track:

  • Public properties or Constructor arguments will automatically be injected by the container.
  • Any component registered in the container that implements the IServiceBehavior or IOperationBehavior interfaces will be easily applicable to your WCF services.

Similarly, there is also a Workflow Foundation integration facility that provides the following functionalities:

  • Host the WorkflowRuntime engine in the container, making it available for any workflow-aware components.
  • Automatically add to the WorkflowRuntime any Workflow services (components inherited from WorkflowRuntimeService base class) or External Data exchange services (components with ExternalDataExchange attribute).

Hope one finds that interesting … :)

DSL News

April 21st, 2008 stiiifff No comments

For those who are interested in Domain-Specific Languages (anybody reading this blog except myself?), there are a couple of interesting news this week:

As a side note, the feature I’m eagerly awaiting in the next version of the DSL Tools is the DSL extensibility one. Imagine being able to extend your base DSL model using plugins, whether it be classes, properties, rules, validations … this opens up a whole new world.

For one of my current project in which I need basic extensibility, I tried to mix the System.Plugin framework with the DSL Tools … I stopped during the process, too complex, too heavy, and used a simpler Provider architecture instead. For more advanced scenarii, I’ll wait for the new model provided by Visual Studio codename “Rosario“.

Categories: Castle Project, DSL, WCF, WPF Tags: , , ,

My top 5 technologies for 2008

January 27th, 2008 stiiifff No comments

Those are the technologies I will definitely try to master in 2008, because they add a real value to the art of software development and allow developers / architects to work at a higher level (less dirty code on the hands lol):

1. Visual Studio DSL Tools : I recently got interested in Domain-Specific Development especially with the wonderfull Visual Studio DSL Tools. Definitely have to practice this more. Guess I will order the book 'Domain-Specific Development with Visual Studio DSL Tools'.
2. WCF : The great (r)evolution that Microsoft delivered as part as .Net 3.0. Any .Net developer should know about it. Need to finish the book 'Programming WCF Services'.
3. WF : The 'unknown sibling' of WCF. I already have some advanced practice with that one (advanced custom activities) as I had a course & used it on a project for several months. Still have to finish reading the book 'Essential Windows Workflow Foundation'.
4. Linq : Definitely need to check the inner workins of Linq to gain a better understanding of it and be able to use it correctly with abstract Repositories & ORM.
5. DDD : Already got a good knowledge of that one, but I want to become an expert as it is gaining more & more popularity as well as visibility while Microsoft is adopting it slowly but surely (Linq to SQL, Entity Framework). 'Applying Domain-Driven Design and Patterns: With Examples in C# and .NET' is a real eye-opener on the subject.

Well, it seems that my schedule for 2008 is already full :) lol

Categories: DDD, DSL, WCF, WF Tags: , , , , ,

Using Castle Windsor in your custom Workflow Activities

January 8th, 2008 stiiifff No comments

A little trick about accessing your Windsor container, containing e.g. your infrastructure services, from your custom activities :)

Castle.Windsor assembly contains a Castle.Windsor.Adapters.ComponentModel namespace with some very interesting & usefull classes …

To get access to my container from my custom activities, here is the approach I choose:

  • Encapsulate my container in a ContainerWrapper (this class does not assume ownership of the wrapped IWindsorContainer).
  • Add the wrapper to the WorkflowRuntime with the AddService method.
  • Access my container through the activity's ActivityExecutionContext (which implements the IServiceProvider interface) by calling the GetService method with IContainerAccessor (or IServiceProvider) as type.

IMHO, Simple & nice :)

This little trick also allows to use a test container containing mocked services for your unit tests … much easier than if your custom activities were accessing the container through a static service locator or a similar static helper class.

Hope this little trick can save you some valuable time ! ;)

Unit Testing custom Workflow Activities

January 8th, 2008 stiiifff No comments

I recently had to create some custom activities that had to receive external data from or send data to external services. As I wanted to be sure that the behavior of my custom activities was correct, I tried to write some unit tests for them. As I found out, there aren’t much articles yet about unit testing such custom activities … here the 2 interesting ones I found:

Hope I can add my 2 cents on the subject with this article. :)

Let’s start by describing how my custom activity look like : I will skip the simple cases in which the activity is not communicating with the outside world (not receiving events, not calling methods) … in order to test such activity, we just need to check the end result of the workflow (output) given an input.

My custom will be slightly more complex as it will be able to receive events and / or call methods using WF’s HandleExternalEventActivity & CallExternalMethodActivity built-in activities. Yet, for simpleness of the example, I will not include any FaultHandler activities or more generally, error-handling code.

Ok, now let’s dig in :)

My activity will use an external service defined by the following interface:

[ExternalDataExchange]
public interface ICustomService
{
    event EventHandler MyEvent;
    string MyMethod(string input);
}

[Serializable]
public class CustomServiceEventArgs : ExternalDataEventArgs
{
    private readonly string input;

    public CustomServiceEventArgs(Guid instanceId, string input) : base(instanceId)
    {
        this.input = input;
    }

    public string Input
    {
        get { return input; }
    }
}

This dumb service contains a simple event and a simple method.
And here is a dumb implementation of this service:

public class CustomService : ICustomService
{
    public event EventHandler<CustomServiceEventArgs> MyEvent;

    public string MyMethod(string input)
    {
        return input.ToUpperInvariant();
    }

    public void RaiseMyEvent(Guid instanceId, string input)
    {
    if (MyEvent != null)
        MyEvent(null, new CustomServiceEventArgs(instanceId, input));
    }
}

The implementation of the MyMethod method is just ‘upper-casing’ the input string.

Now, I build a custom sequence activity (inherited from SequenceActivity) that do 2 things:

  • Wait for the event MyEvent to be triggered on ICustomService service.
  • When the event is triggered, keep the value of the Input property of the received CustomServiceEventArgs object in a property of the custom activity.
  • Call the MyMethod method of the ICustomerService, passing in the value of the Input property.

(For brievity purpose, I don’t show the code / screenshots of this custom activity, you can have a look at it in the source code provided at the end of this article).

Now, let’s say I build a simple Sequential workflow containing only my custom activity, and I would like to write a unit test verifying that my custom activity is working correctly.

The first approach is to test the output of the workflow, based on a pre-defined input … a test method to do that could look more or less like this (using NUnit):

// This test just verify that the output of the workflow is as expected.
// Some problems with this approach:
//  - The test is dependent on the ICustomService service's implementaion class (CustomService).
//  - Ok for simple custom activities ... maybe less reliable for complex event-based custom activities.
[Test]
public void SimpleTest()
{
    using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
    {
        ExternalDataExchangeService dataExchange = new ExternalDataExchangeService();
        workflowRuntime.AddService(dataExchange);

        // Create instance of ICustomService using concret implementation class CustomService
        CustomService customService = new CustomService();
        dataExchange.AddService(customService);

        string workflowOutput = null;

        AutoResetEvent waitHandle = new AutoResetEvent(false);
        workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
        {
            workflowOutput = e.OutputParameters["WorkflowOutput"] as string;
            waitHandle.Set();
        };
        workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };

        WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(TestWorkflow));
        instance.Start();

        // Raise event using helper method in implementation class
        customService.RaiseMyEvent(instance.InstanceId, "inputdata");

        waitHandle.WaitOne();

        // Check that output is as expected
        Assert.AreEqual("INPUTDATA", workflowOutput);
    }
}

As you can read it in the comment of the test method, this unit test has some limitations:

  • The test is dependent on the existing ICustomService service’s implementaion class (CustomService).
  • It might be ok for simple custom activities … but it will most probably be less reliable for complex event-based custom activities.

A better way IMHO might be to use a mock object for the ICustomerService service, and define expectations on it. This approach is show here (using NUnit / RhinoMocks):

// This test  verify that the output of the workflow is as expected as well as the 'behavior'
// (subscription to external events, calls to external methods, and in which order they occur)
// Some advantages of this approach:
//  - The test is independent on the ICustomService service's implementation class (CustomService)
//        -> the CustomService class can be tested separately with another test case.
//  - Deeper testing of the actual behaviour of the custom activity regarding external inputs / outputs (events / methods)
[Test]
public void AdvancedTest()
{
    using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
    {
        MockRepository mockRepository = new MockRepository();

        // Create mock object for service ICustomerService
        ICustomService mockCustomService = mockRepository.CreateMock<ICustomService>();

        // We need an 'event raiser' for the 'MyEvent' event of the ICustomService
        IEventRaiser raiseMyEvent = null;

        // Declare that the expectations have to occur in the specified order
        using (mockRepository.Ordered())
        {
            // Declare expectations on mock service
            mockCustomService.MyEvent += null; // Create an expectation that someone will subscribe to this event
            LastCall.IgnoreArguments(); // we don't care who is subscribing
            raiseMyEvent = LastCall.GetEventRaiser(); // Get event raiser for the last event, in this case, MyEvent

            // Create an expectation that someone will call MyMethod with "inputdata" as parameter,
            // and instruct mock object to return "INPUTDATA" in that case
            Expect.Call(
                mockCustomService.MyMethod("inputdata")
            ).Return("INPUTDATA");
        }
        mockRepository.ReplayAll();    // Expectations declared, we are ready to start the test

        ExternalDataExchangeService dataExchange = new ExternalDataExchangeService();
        workflowRuntime.AddService(dataExchange);
        dataExchange.AddService(mockCustomService);

        string workflowOutput = null;

        AutoResetEvent waitHandle = new AutoResetEvent(false);
        workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
        {
            workflowOutput = e.OutputParameters["WorkflowOutput"] as string;
            waitHandle.Set();
        };
        workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };

        WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(TestWorkflow));
        instance.Start();

        // Raise the 'MyEvent' event of the mocked service
        raiseMyEvent.Raise(null, new CustomServiceEventArgs(instance.InstanceId, "inputdata"));

        waitHandle.WaitOne();

        // Check output data AND expectations
        Assert.AreEqual("INPUTDATA", workflowOutput);
        mockRepository.VerifyAll();
    }
}

Advantages of using this approach :

  • The test is independent on the ICustomService service’s implementation class (CustomService) -> the CustomService class can be tested separately with another test case (which is actually recommended).
  • Deeper testing of the actual behavior of the custom activity regarding external inputs / outputs (events / methods) … some might say that the test is then more tightly coupled with the implementation of the custom activity … this can be debated. :)

IMHO, this second approach allows to build unit tests that are much more reliable when you want to make sure you can detect any regression in the output but also in the behaviors of your custom activities.

I will soon post a link pointing to the sample workflow test project with the full source code illustrating this article.

Not all aspects of unit testing workflows were treated here but at least an interesting one that, I hope, will help you create better& smarter custom activities! :)

Categories: TDD, WF Tags: , , , ,