Inversion of Control with WCF and Unity

Lately, I often talks with friends and colleagues about Inversion of Control (IOC) and WCF. Then, I’ve decided to publish this post and explain the necessary steps to get IoC in WCF. For this example, let’s get to use Unity ad framework for IoC.

First, the necessary components are:

  • InstanceProvider: it is the component that creates the service instance. It uses the UnityContainer;
  • ServiceBehavior: creates the InstanceProvider and allows to use it in the current context;
  • ServiceHost: handles the environment of our service. The ServiceHost configures the service for use and then it allows to apply the created ServiceBehavior instance;

We then get: UnityInstanceProvider, UnityServiceBehavior and UnityServiceHost.

UnityInstanceProvider

The first step is to create the InstanceProvider. The code is really simple:

  1: internal class UnityInstanceProvider : IInstanceProvider
  2: {
  3:     private readonly IUnityContainer container;
  4:     private readonly Type contractType;
  5: 
  6:     public UnityInstanceProvider(IUnityContainer container, Type contractType)
  7:     {
  8:         this.container = container;
  9:         this.contractType = contractType;
 10:     }
 11: 
 12:     public object GetInstance(InstanceContext instanceContext)
 13:     {
 14:         return GetInstance(instanceContext, null);
 15:     }
 16: 
 17:     public object GetInstance(InstanceContext instanceContext, Message message)
 18:     {
 19:         return container.Resolve(contractType);
 20:     }
 21: 
 22:     public void ReleaseInstance(InstanceContext instanceContext, object instance)
 23:     {
 24:         container.Teardown(instance);
 25:     }
 26: }

The first constructor’s parameters is the instance of the UnityContainer and the second is the specific endpoint contract. Both are used by the GetInstance to resolve the service’s instance. Naturally, the method could be better.

UnityServiceBehavior

The ServiceBehavior, as mentioned above, creates the InstanceProvider for the specifiv service endpoint:

  1: public class UnityServiceBehavior : IServiceBehavior
  2: {
  3:     private readonly IUnityContainer container;
  4: 
  5:     public UnityServiceBehavior(IUnityContainer container)
  6:     {
  7:         this.container = container;
  8:     }
  9: 
 10:     public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 11:     {
 12:     }
 13: 
 14:     public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
 15:     {
 16:     }
 17: 
 18:     public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 19:     {
 20:         foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
 21:         {
 22:             foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
 23:             {
 24:                 if (endpointDispatcher.ContractName != "IMetadataExchange")
 25:                 {
 26:                     string contractName = endpointDispatcher.ContractName;
 27:                     ServiceEndpoint serviceEndpoint = serviceDescription.Endpoints.FirstOrDefault(e => e.Contract.Name == contractName);
 28:                     endpointDispatcher.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(this.container, serviceEndpoint.Contract.ContractType);
 29:                 }
 30:             }
 31:         }
 32:     }
 33: }

The constructor gets from ServiceHost the container’s instance. Then the ApplyDispatchBehavior assigns the instance to the UnityInstanceProvider with the contracts used to resolve the service instance. Finally the UnityInstanceProvider is assigned to InstanceProvider property of DispatchRuntime for each EndpointDispatcher.

UnityServiceHost

The finaly step is to create the ServiceHost:

  1: public class UnityServiceHost : ServiceHost
  2: {
  3:     private IUnityContainer unityContainer;
  4: 
  5:     public UnityServiceHost(IUnityContainer unityContainer, Type serviceType) : base(serviceType)
  6:     {
  7:         this.unityContainer = unityContainer;
  8:     }
  9: 
 10:     protected override void OnOpening()
 11:     {
 12:         base.OnOpening();
 13: 
 14:         if (this.Description.Behaviors.Find<UnityServiceBehavior>() == null)
 15:         {
 16:             this.Description.Behaviors.Add(new UnityServiceBehavior(this.unityContainer));
 17:         }
 18:     }
 19: }

The code is really simple. The ServiceHost's constructor gets the container and the service type as parameters. In the OnOpening method override the ServiceHost checks if the UnityServiceBehavior is already added to Service’s behaviors. If not, it creates the instance and pass the container’s instance to the contructor.

Utilizzo in una applicazione console self-hosted

Now we are ready. This is the sample configuration we'll use in our service:

  1: <?xml version="1.0" encoding="utf-8" ?>
  2: <configuration>
  3:   <configSections>
  4:     <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  5:   </configSections>
  6:   
  7:   <unity>
  8: 
  9:     <containers>
 10: 
 11:       <container>
 12:         <types>
 13:           
 14:           <type type="DotNetSide.WCF.IoC.Console.InnerBookService, DotNetSide.WCF.IoC.Console"
 15:                 name="inner"/>
 16: 
 17:           <type type="DotNetSide.WCF.IoC.Console.IBookService, DotNetSide.WCF.IoC.Console"
 18:                 mapTo="DotNetSide.WCF.IoC.Console.BookService, DotNetSide.WCF.IoC.Console">
 19:             <typeConfig>
 20:               <constructor>
 21:                 <param name="innerService" parameterType="DotNetSide.WCF.IoC.Console.InnerBookService, DotNetSide.WCF.IoC.Console">
 22:                   <dependency name="inner" />
 23:                 </param>
 24:               </constructor>
 25:             </typeConfig>
 26:           </type>
 27: 
 28:         </types>
 29:       </container>
 30: 
 31:     </containers>
 32:     
 33:   </unity>
 34: 
 35: </configuration>

Simply must be created an InnerBookService instance and then get it into the BookService’s constructor, an IBookService contract implementation:

  1: [ServiceContract]
  2: internal interface IBookService
  3: {
  4:     [OperationContract]
  5:     Book ReadBook(string bookId);
  6: }
  7: 
  8: class BookService : IBookService
  9: {
 10:     private readonly InnerBookService innerService;
 11: 
 12:     public BookService(InnerBookService innerService)
 13:     {
 14:         this.innerService = innerService;
 15:     }
 16: 
 17:     public Book ReadBook(string bookId)
 18:     {
 19:         return this.innerService.ReadBook(bookId);
 20:     }
 21: }
 22: 
 23: class InnerBookService
 24: {
 25:     public Book ReadBook(string bookId)
 26:     {
 27:         return new Book()
 28:         {
 29:             Title = "WCF",
 30:             Description = "A book on Windows Communication Foundation"
 31:         };
 32:     }
 33: }

Finally we build the ServiceHost with the instance of the UnityContainer:

  1: var unityContainer = new UnityContainer();
  2: var configurationSection = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
  3: configurationSection.Containers.Default.Configure(unityContainer);
  4: 
  5: Uri serviceAddress = new Uri("http://localhost:9001/BookService");
  6: Uri mexAddress = new Uri("http://localhost:9001/BookService/mex");
  7: using (UnityServiceHost host = new UnityServiceHost(unityContainer, unityContainer.Resolve<IBookService>().GetType()))
  8: {
  9:     host.Description.Behaviors.Add(new ServiceMetadataBehavior());
 10:     host.AddServiceEndpoint(typeof(IBookService), new BasicHttpBinding(), serviceAddress);
 11:     host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), mexAddress);
 12: 
 13:     host.Open();
 14: 
 15:     System.Console.Read();
 16: 
 17:     host.Close();
 18: }

We also add a WS-MetadataExchange endpoint. In this way we can create our client and try to call the service.

Actually, the UnityServiceHost is not necessary but helps us to encapsulate the behavior creation. We can also write:

  1: using (ServiceHost host = new ServiceHost(unityContainer.Resolve<IBookService>().GetType()))
  2: {
  3:     host.Description.Behaviors.Add(new UnityServiceBehavior(unityContainer));
  4:     // ...
  5: }
  6: 

Feedback?

bye

kick it on DotNetKicks.com

Published Tuesday, March 24, 2009 12:11 AM by fabioc
Filed under: ,

Comments

# re: Inversion of Control with WCF and Unity

Monday, March 23, 2009 10:43 PM by Jason

Hello,

Do you know if Unity will be replaced with MEF?

# re: Inversion of Control with WCF and Unity

Wednesday, March 31, 2010 2:50 AM by Kalyan

Is is possible to get the complete solution for download, as I am working on wcf and IoC

# re: Inversion of Control with WCF and Unity

Tuesday, April 6, 2010 12:07 PM by Chris P

Great post, can you please provide a download link for the sample code? Thanks again!

# re: Inversion of Control with WCF and Unity

Tuesday, January 18, 2011 1:07 PM by R. Kevin Burton

I would like to register a chain of methods to be called before and after a target imploementation. This post comes close to interception but would you mind providing a little more feedback on implementing multiple interception methods?

# re: Inversion of Control with WCF and Unity

Sunday, September 9, 2012 10:08 PM by Guest

What's up everyone, it's my first go to see at this site,

and paragraph is really fruitful in favor of me, keep up posting these types of posts.

# re: Inversion of Control with WCF and Unity

Monday, October 8, 2012 11:10 AM by Almond

You can eliminate 3 to unique pounds in one particular week.

In which to lose weight, chew on lean meat,

combined with prepare it all through a healthy process.

It can get a number of weeks before ones doctor can appear the right anti-depressant to fit an condition.

# re: Inversion of Control with WCF and Unity

Friday, November 23, 2012 10:50 AM by Morley

We stumbled over here from a different web address and

thought I might as well check things out. I like

what I see so i am just following you. Look forward to looking over your web page repeatedly.

# re: Inversion of Control with WCF and Unity

Sunday, November 25, 2012 6:22 PM by Durden

Hi there just wanted to give you a brief heads up and let you know a few

of the pictures aren't loading correctly. I'm not sure why but I think its a

linking issue. I've tried it in two different internet browsers and both show the same results.

# re: Inversion of Control with WCF and Unity

Monday, November 26, 2012 12:55 AM by Badger

Thanks for another great article. Where else may anyone get that type of info in such an ideal way of writing?

I have a presentation subsequent week, and I am

at the search for such info.

# re: Inversion of Control with WCF and Unity

Monday, November 26, 2012 4:57 AM by Mcneal

Wow, wonderful blog layout! How long have you been blogging for?

you make blogging look easy. The overall look of your

website is fantastic, as well as the content!

# re: Inversion of Control with WCF and Unity

Tuesday, December 18, 2012 6:24 AM by Rowell

Good day, your websites are really good. We do appreciate you excellent posts.

# re: Inversion of Control with WCF and Unity

Saturday, February 16, 2013 12:06 AM by Register

Your current report has proven useful to us. It’s very informative

and you're simply naturally very knowledgeable in this field. You have exposed my face for you to different thoughts about this specific subject together with intriguing, notable and reliable articles.

# re: Inversion of Control with WCF and Unity

Thursday, February 21, 2013 11:03 PM by Haggard

Nice post. I used to be checking constantly this blog and I am inspired!

Extremely useful info specially the closing part :) I deal

with such info much. I was looking for this certain

information for a long time. Thanks and best of luck.

# re: Inversion of Control with WCF and Unity

Monday, March 11, 2013 4:38 PM by Sumner

Your current report features confirmed helpful to myself.

It’s very helpful and you really are certainly quite experienced of this type.

You get opened my personal eyes in order to varying opinion of this

kind of subject with intriguing and reliable content material.

# re: Inversion of Control with WCF and Unity

Thursday, March 14, 2013 2:35 AM by Dugas

I'm now not sure the place you are getting your information, but good topic. I must spend some time learning much more or understanding more. Thanks for wonderful info I used to be looking for this info for my mission.

# re: Inversion of Control with WCF and Unity

Thursday, March 14, 2013 8:45 PM by Mueller

Your own write-up provides established useful to me. It’s quite educational and you're obviously extremely educated in this region. You get opened my personal sight in order to numerous opinion of this subject matter using interesting and sound content material.

# re: Inversion of Control with WCF and Unity

Tuesday, March 19, 2013 10:09 PM by Elston

Great delivery. Great arguments. Keep up the great spirit.

# re: Inversion of Control with WCF and Unity

Friday, March 22, 2013 5:59 AM by Minnick

Hello friends, how is the whole thing, and what you desire to say

about this paragraph, in my view its truly remarkable designed

for me.

# re: Inversion of Control with WCF and Unity

Saturday, March 23, 2013 12:09 PM by Carmichael

Generally I don't read article on blogs, however I wish to say that this write-up very forced me to check out and do it! Your writing style has been amazed me. Thanks, quite nice post.

# re: Inversion of Control with WCF and Unity

Wednesday, March 27, 2013 10:32 PM by Schwartz

I know this website provides quality based content and additional material, is there any other site which

presents these kinds of things in quality?

# re: Inversion of Control with WCF and Unity

Thursday, April 11, 2013 4:05 PM by Humphreys

My partner and I stumbled over here different web

address and thought I might as well check things out.

I like what I see so now i am following you. Look forward to looking at your web page

yet again.

# re: Inversion of Control with WCF and Unity

Thursday, April 11, 2013 9:55 PM by Vazquez

Hi I am so glad I found your website, I really found

you by error, while I was searching on Aol for something else,

Regardless I am here now and would just like to say kudos for a tremendous post and a all round

entertaining blog (I also love the theme/design), I don’t have time to look over it all at the minute but

I have saved it and also added in your RSS feeds, so when I have time I will be back to read much

more, Please do keep up the excellent work.

# re: Inversion of Control with WCF and Unity

Monday, April 15, 2013 9:19 PM by Gallardo

Your own report has verified helpful to me. It’s very educational and

you really are obviously very experienced in this region.

You get opened up my personal sight in order to different

opinion of this subject matter with interesting and reliable written content.

# re: Inversion of Control with WCF and Unity

Monday, April 22, 2013 5:10 PM by Christianson

Hi there to every one, the contents present at this site are truly awesome for people knowledge, well, keep up

the nice work fellows.