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:

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

    • jheppinstall says:

      Hi Gopi, is there any part of the code in particular that you would like to see?

      • Gopi says:

        Hi James ,
        Thank you for your quick response.
        I am try to build similar application. the flow of the application , if i understand correctly, MVC –> WCF–> Repository . Do we register repository with wcfserviceFactory or with MVC Global.ascx ?

        And if you can share with me sample , complete one mvc , wcf , contracts , entities , repository ? I am more interested in integration point not for logic one.

      • jheppinstall says:

        Hi Gopi,

        The repositories are registered in the Global.asax in the service host, as described in the last section in the previous post in the series:

        Windows Communication Foundation – Resolving WCF service dependencies with Unity

        MVC should not know (or care) about the repositories.

        Give me a little time and I will try to make a full solution available for download.

  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 to Gopi Cancel reply