Monday 25 February 2008

NServiceBus

I subscribed to Udi Dahan's blog recently (http://udidahan.weblogs.us/). I saw him present a session called "Designing High Performance, Persistent Domain Models" at Tech-Ed 2007 in Barcelona. It was one of the best sessions I saw during the week. How he got a talk with NHibernate demo material into Tech-Ed I'll never know.

I read through some of the old blog posts to catch up on what he'd been doing since Tech-Ed and I noticed he'd been working on a open source messaging framework called "NServiceBus" (http://www.nservicebus.com/).

This is interesting because I frequently encounter projects that require some kind of message bus with pub/sub features but don't want to take the plunge with BizTalk as its either too heavy weight or the license cost is prohibitive.

The project seems to be progressing, version 1.7 has been released at the time of writing and there is an active news group (http://tech.groups.yahoo.com/group/nservicebus/).

I will evaluate the framework at some point and report back.


Saturday 23 February 2008

WCF Services and Dependency Injection with Castle

You might encounter a situation where you are leveraging the dependency injection design pattern in your application. At first this might seem problematic to implement if you are using WCF Services.

For example, you may have the following classes:

public interface ICustomerRepository

{

    // Code

}

 

public class CustomerRepository : ICustomerRepository

{

    // Code

}

 

[ServiceContract]

public interface ICustomerService

{

    [OperationContract]

    void AddCustomer(AddCustomerRequest addCustomerRequest);

}

 

public class CustomerService : ICustomerService

{

    private readonly ICustomerRepository _customerRepository;

 

    public CustomerService(ICustomerRepository customerRepository)

    {

        _customerRepository = customerRepository;

    }

 

    /// <remarks />

    public void AddCustomer(AddCustomerRequest addCustomerRequest)

    {

        // Do stuff

        // _customerRepository.SomeMethod(someParameter);

    }

}

The problem is that as your WCF Service is instantiated by the WCF plumbing, you don't have any control over the creation of this class. How do you "inject the dependency"? How do you supply the "ICustomerRepository" to the "CustomerService"? If you are using the Windsor Container part of the Castle framework (http://www.castleproject.org/) as your Component Container, it has a Facility that enables us to do this.

Using the "CustomerService" example above, you need to do three things in your Web Services project.

1. Modify the .svc file

Create your "CustomerService.svc" file as follows:

<%@ ServiceHost Service="CustomerService" Factory="Castle.Facilities.WcfIntegration.WindsorServiceHostFactory, Castle.Facilities.WcfIntegration" %>

Note the differences between a standard svc file.

2. Modify your Global.asax

Next you need to instantiate a Windsor Container, do this in a Global.asax file as follows (you might have to add one to your project):

public class Global : HttpApplication

{

    private readonly IWindsorContainer _container =

        new WindsorContainer(new XmlInterpreter());

 

    protected void Application_End(object sender, EventArgs e)

    {

        if (_container != null)

            _container.Dispose();

    }

 

    protected void Application_Start(object sender, EventArgs e)

    {

        WindsorServiceHostFactory.RegisterContainer(_container.Kernel);

    }

}

3. Configure Castle

Configure Castle in the usual way, you need to include your "CustomerService" and "CustomerRepository" classes in the configuration. An example is as follows:

<configSections>

  <section

    name="castle"

    type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />

</configSections>

 

<castle>

  <components>

    <component

      id="CustomerRepository"

      service="Acme.PetSop.ICustomerRepository, myAssembly"

      type="Acme.PetSop.CustomerRepository, myAssembly" />

    <component

      id="CustomerService"

      service="Acme.PetSop.ICustomerService, myAssembly"

      type="Acme.PetSop.CustomerService, myAssembly" />

  </components>

</castle>

Please note that your "Service" value in the .svc file must match the "id" value in the Castle configuration.

You need to have the "Castle.Facilities.WcfIntegration.dll" assembly referenced by your Web Application project. At the time of writing this assembly is not in the latest Castle release and can only be found in the nightly builds.

The Castle documentation for the WCF Facility can be found here: http://www.castleproject.org/container/facilities/trunk/wcf/index.html


Saturday 16 February 2008

Using the MSTest AspNetDevelopmentServer Attribute

If you want to have Integration-type tests and run automated tests against a web service (or web site), with MSTest you can use the "AspNetDevelopmentServer" Attribute on your Test Method. There is a gotcha with the use of this attribute. See the following example:

[TestClass]

public class MyTestClass

{

    [TestMethod]

    [AspNetDevelopmentServer("name", "path")]

    public void MyTestMethod()

    {

        // Do stuff

    }

}



You might be tempted to put the "name" and "path" properties in constants somewhere. Unfortunately if you do this, the "AspNetDevelopmentServer" Attribute will cease to function and the ASP.NET Development Server will not be activated when your tests run. Why is a mystery. So, keep the property values as hard-coded strings in-line.

Friday 15 February 2008

Installing Visual Studio 2005 Extensions for .NET Framework 3.0 after Visual Studio 2008

This took me a while to resolve.

If you come to install the Visual Studio 2005 Extensions for .NET Framework 3.0 after you have installed .NET Framework 3.0 SP1 or Visual Studio 2008 (which installs .NET 3.0 SP1) then you will receive get a message saying you need to have .NET Framework 3.0 installed (as in, no Service Pack). Obviously you can't because you'll have to un-install/re-install a whole chain of stuff.

A small registry hack will let you re-try the installation, add the following to your registry:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{15095BF3-A3D7-4DDF-B193-3A496881E003}]
"DisplayName"="Microsoft .NET Framework 3.0"

This will fool the installer. I'd recommend removing the registry entry afterwards (that's what I did).

More details here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2550726&SiteID=1

About Me