Windows Communication Foundation – Resolving MVC client WCF ChannelFactory dependencies with Unity

This series of posts will talk about Windows Communication Foundation, starting with an introduction into the technology and how to use it in you project, moving onto more advanced topics such as using an IOC container to satisfy dependencies in your services.
Posts in this series:

In the previous post we looked at how it was possible to use ChannelFactory to consume a WCF service from an MVC controller without using a proxy generated from the service WSDL.

The View action of the ProductController looked like this:

public ActionResult View(int productId)
{
    var factory = new ChannelFactory<IProductService>("WSHttpBinding_IProductService");
    var wcfClientChannel = factory.CreateChannel();
    var result = wcfClientChannel.GetProductById(productId);

    var model = new ViewProductModel 
        { 
            Id = result.Id, 
            Name = result.Name, 
            Description = result.Description 
        };

    return View(model);
}

This approach is less than ideal. The ChannelFactory creation is a little awkward and would be littered throughout the controller code creating duplication.

It would be better if we could just use Unity to inject a dependency to the WCF service in the Controller constructor like this;

private readonly IProductService productService;

public ProductController(IProductService productService)
{
    this.productService = productService;
}

public ActionResult View(int productId)
{
    var result = productService.GetProductById(productId);

    var model = new ViewProductModel 
        { 
            Id = result.Id, 
            Name = result.Name, 
            Description = result.Description 
        };

    return View(model);
}

If we tried to run this MVC would not be able to create the controller as there is no longer a parameterless constructor. Since version 3 MVC has introduced a mechanism for using IoC dependency resolution to resolve Controller dependencies through IDependencyResolver. Simply implement the interface and register using DependencyResolver.SetResolver.

If your needs are simple, then there are very simple implementations that will serve you well, however if you want to resolve dependencies that implement IDisposable then you need to be a bit more careful, as simple implementations often do not cater for IDisposable at all.

I am going to recommend a NuGet package to save us from implementing IDependencyResolver as I want to focus on how we can resolve WCF service dependencies. Unity.MVC3  is a nice little package that makes setting up Unity with MVC very easy. Although it was built for MVC3, version 4 uses the same mechanism and the package continues to function in the correct manner. You can read more about how the package functions here.

Install the package and open Bootstrapper.cs. Inside there is a BuildUnityContainer() section, this is where we need to register the dependencies with Unity. But when we ask for an IProductService what should we return? We need a new WCF channel for the IProductService based on the endpoint settings we defined in the web.config in the previous post. The code to do this is:

private static IUnityContainer BuildUnityContainer()
{
    var container = new UnityContainer();

    container.RegisterType<IProductService>(
        new ContainerControlledLifetimeManager(),
        new InjectionFactory(
            (c) => new ChannelFactory<IProductService>("WSHttpBinding_IProductService").CreateChannel()));          

    return container;
}

So what does this actually do? The first parameter is the type of lifetime manager we require. A Unity lifetime manager describes how dependencies are created and destroyed and the lifetime those dependencies have. In this case a ContainerControlledLifeTimeManager means that the same instance is returned for each call (also known as Singleton instance). This is desirable for creating WCF channels  as it is a comparatively expensive operation so we only want to create the channel once for the lifetime of the Unity container. There are several other Unity Lifetime Managers that are useful in different circumstances.

The next parameter introduces a factory function that tells Unity how to create the required concrete type. In our case we are going to create a new WCF Channel using ChannelFactory for the named client endpoint we set up in the web.config.

The only thing we need to do is to call Bootstrapper.Initialise() from Application_Start() in Global.asax and we are good to go. The controller is now completely decoupled from the WCF ChannelFactory, leaving a much cleaner implementation.

Posts in this series:

Advertisements

21 Responses to Windows Communication Foundation – Resolving MVC client WCF ChannelFactory dependencies with Unity

  1. Pingback: An Introduction to Windows Communication Foundation – Creating a basic service « James Heppinstall: On Development

  2. Pingback: Windows Communication Foundation – Consuming a WCF service with ChannelFactory « James Heppinstall: On Development

  3. Pingback: Windows Communication Foundation – Resolving WCF service dependencies with Unity « James Heppinstall: On Development

  4. Gopi says:

    could you please share the code

  5. Gopi says:

    Hi James , thank you for the note . I will be waiting for your example solution .

    Regards
    Gopi

  6. Vinni1 says:

    Hi James, Is the code available for download yet?

    • jheppinstall says:

      Hi Vinni1,

      No code for download at the moment I’m afraid. However all the code needed is included as part of the post so it shouldn’t be too difficult to use it in your project.

  7. Vinnie says:

    Hi James, Thanks for responding back.

    The problem I am facing is when I run the application and it calls the constructor method as below:

    var result = service.GetContact(id);

    I get an error saying “The requested service, ‘http://localhost:4212/ContactService.svc’ could not be activated”

    My ContactService.svc.cs looks like

    When I comment the factory line, the code works, not as expected but won’t give error.

    Do you have any idea about what wrong I might be doing.

    Cheers
    Vinnie

    • jheppinstall says:

      Hi Vinnie,

      Are you using an IOC container to satisfy your dependencies? Some work is required to make the factory part work. This is outlined in my previous WCF posts. Have you tried navigating to the service url in a browser. This may give you more information.

      Cheers

      James

  8. Vinnie says:

    James,

    I have blindly followed the pattern you mentioned and wrote my code accordingly. You can ask me any piece of code, and I shall have that implemented, so kindly let me know, where I might be doing wrong.

    Cheers
    Vinod

  9. Vinnie says:

    Hi James,

    I didn’t received any mail from you. Could you type your email id and send you the email.

    Cheers

  10. Vinnie says:

    Hi James, I have sent you an email, kindly check.

    Cheers

  11. bronumski says:

    Hi James,

    Creating the channel is not the expensive part, it is creating the ChannelFactory. It is best to close of the channel as soon as you are done with it so that the channel can be put back into the pool.

    Also if a channel fails doing a call it goes into a faulted state. If you cache the channel around you will never be able to use it again.

  12. Pingback: Moving MVC-style service layer under WCF | Technology & Programming

  13. charanait49@gmail.com says:

    What if proxy goes to a faulted state.. how and where to create a channel factory

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: