Create Proxy-less WCF client with Unity Configuration

May 6, 2010 at 4:42 AM

I would like to use the configuration file to register a proxy-less WCF client via Unity.  I have figured out how do this at run-time, but I would really like to do this at design time.  Say I have a WCF service contract called IMyService, I can register it at runtime with the following code:

 

IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService>(new ContainerControlledLifetimeManager(),
                                             new InjectionFactory(
                                                 (c) => new ChannelFactory<IMyService>("MyService_IMyService").CreateChannel()));

 

This is great, and it works perfectly, but how do I do the same thing via the config file at design time?  I'm assuming that this is actually possible, but haven't been able to figure out how to do so at this point.  This is actually quite simple to do using Spring.Net, as in the example below:

 

<object scope="request" id="MyServiceClient" type="MyService.IMyService, MyService" singleton="false" factory-object="MyServiceClientFactory" factory-method="CreateChannel">
</object>

<object id="MyServiceClientFactory" type="System.ServiceModel.ChannelFactory&lt;MyService.IMyService&gt;, System.ServiceModel" singleton="true">
    <constructor-arg name="endpointConfigurationName" value="MyService_IMyService" />
</object>

 

My preference would be to use Unity framework for my IOC.  Any help would be greatly appreciated.

Thanks,

Nick

May 6, 2010 at 4:59 AM

Here's a related thread on registering factory method in config file - http://unity.codeplex.com/Thread/View.aspx?ThreadId=204366..  It is not directly supported, but doable.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

May 6, 2010 at 1:24 PM

Is there any chance that this notion of configuring a factory would be added to Unity configuration at any point in the near or distant future?

May 7, 2010 at 2:11 AM

It's possible, I've already seen several questions here asking how to do this.  What you could do for now is to log this in the issue tracker and get people to vote :)

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 25, 2011 at 8:42 PM
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService>(new ContainerControlledLifetimeManager(),
                                             new InjectionFactory(
                                                 (c) => new ChannelFactory<IMyService>("MyService_IMyService").CreateChannel()));


 

Looks really cool.  But does the LifetimeManager controll the life of the ChannelFactory or the Channel or both?

I'm new to Unity2.0 and I'd like to inject my dynamically generated WCF proxies into my MVC Controllers.  This looks like it'll work but I'm concerned about when things will get Disposed.

thanks

Perry

Jan 25, 2011 at 9:18 PM

Perry,

The UnityContainer will create that instance of the Channel, once and only once.  So, as long as the Channel never closes, you will have the same Channel available throughout the lifetime of the application.  I have changed all of my Services so that instead of using the ContainerControlledLifeTimeManager (singleton), to TransientLifetimeManager.  This way, everytime I need the service from the UnityContainer, it creats a new instance.  I also close the Channel when I'm done using it as well.  We discovered that there were memory leaks occurring when we created that singleton instance of the Channel, and that is why we create a new instance on every call now.

Thanks,

Nick

Feb 12, 2011 at 3:59 PM

How about this, from my global.asax.cs from a MVC2 application:

        protected void Application_BeginRequest()
        {
            var requestContainer = InitRequestContainer(applicationContainer);
            HttpContext.Current.Items["container"] = requestContainer;
            ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(requestContainer));
        }

        protected void Application_EndRequest()
        {
            var requestContainer = HttpContext.Current.Items["container"] as IUnityContainer;
            if (requestContainer != null)
                requestContainer.Dispose();
        }

        private static IUnityContainer InitRequestContainer(IUnityContainer parentContainer)
        {
            var requestContainer=parentContainer.CreateChildContainer();
            requestContainer.RegisterType<ChannelFactory<ICatalogService>, ChannelFactory<ICatalogService>>
                (new ContainerControlledLifetimeManager(), new InjectionConstructor(string.Empty));
            requestContainer.RegisterType<ICatalogService>(new InjectionFactory(c => c.Resolve<ChannelFactory<ICatalogService>>().CreateChannel()));
            return requestContainer;
        }

the "requestContainer" gets created and initialized in the Application_BeginRequest(), it will be Disposed when the Unity container is disposed in the Application_EndRequest. When Unity goes to create a Controller that needs an ICatalogService it will first resolve the ChannelFactory().  The ChannelFactory is set for ContainerControlledLifetime so we will only get one ChannelFactory created per request, even if we need many ICatalogService's or if one of the calls on the one of the channels receives a fault and throws and exception.   When the UnityControllerFactory constructs a Controller that doesn't need an ICatalogService, the expensive ChannelFactory will not be created.

Perry

Oct 17, 2011 at 7:39 AM
Edited Oct 17, 2011 at 1:25 PM

-