• Code
  • Tags
  • Users
  • Titles
  • Log in
  • Feedback
  • FAQ
Share Code
Welcome to ForkCan.com

ForkCan is all about sharing code in a social way.

Discuss, debate or argue with other devs about their or your own code.

Give other devs feedback or make a Fork (Make a better version of a shared code).

Rate the code, if you use the code mark it as used so others can see if the shared code is used by someone.

Help each other to be better devs and to be more productive.


Features not working yet:

Flag a post


QR Code

Tiny Url

http://4kcan.com/s/Mjk2

Related Code
Dependency Injection-enabled WCF Instance Provider
Keep Entity Framework ObjectContext in a WCF Service OperationContext
Unity Controller Factory for ASP.NET MVC 3.0
WCF RIA Services Unity 2.0 DomainService Factory
HttpContextLifetimeManager for Unity
ASP.NET MVC 4.0 Web API Message logger for .Net 4.0
Simple light ObjectFactory using Unity

WCF Service factory for using Microsoft Unity 2.0 to create an instance of a Service

Several classes that are needed to use Unity 2.0 to create a WCF Service and to handle dependency injection.

1
2.67k 0 0 0 0 2

UnityServiceHostFactory, a WCF host factory:

using System;
using System.ServiceModel.Activation;
using System.ServiceModel;
using Infrastructure.IoContainer;

namespace Services.Host.Infrastructure
{
   public abstract class UnityServiceHostFactory : ServiceHostFactoryBase
   {
     private readonly IUnityConfiguration _unityConfiguration;

     protected UnityServiceHostFactory(IUnityConfiguration unityConfiguration)
     {
        _unityConfiguration = unityConfiguration;
     }

     public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
     {
        var serviceType = Type.GetType(constructorString);

        var host = new UnityServiceHost(serviceType, baseAddresses);

        Unity.Configure(_unityConfiguration);

        host.Container = Unity.Current;

        return host;
      }
   }
}

UnityServiceHost, a WCF Service host:

using System;
using System.ServiceModel;
using Microsoft.Practices.Unity;

namespace Services.Host.Infrastructure
{
   public class UnityServiceHost : ServiceHost
   {
       public IUnityContainer Container { set; get; }


       public UnityServiceHost() : base() {}


       public UnityServiceHost(
                Type serviceType,
                params Uri[] baseAddresses) : base(serviceType, baseAddresses) {}


       protected override void OnOpening()
       {
          if (Container == null)
              throw new ApplicationException("The UnityServiceHost's Container property can't be null");

           new UnityServiceBehavior(Container).AddToHost(this);
           base.OnOpening();
       }
   }
}

UnityServiceBehavior, a WCF Service behavior:

using System.Linq;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel;
using Microsoft.Practices.Unity;
using System.ServiceModel.Channels;
using System.Collections.ObjectModel;

namespace Services.Host.Infrastructure
{
   public class UnityServiceBehavior : IServiceBehavior
   {
      public UnityInstanceProvider InstanceProvider { get; set; }

      private ServiceHost _serviceHost;


      public UnityServiceBehavior()
      {
         InstanceProvider = new UnityInstanceProvider();
      }


      public UnityServiceBehavior(IUnityContainer unity)
      {
         InstanceProvider = new UnityInstanceProvider {Container = unity};
      }


      public void ApplyDispatchBehavior(
                                        ServiceDescription serviceDescription,
                                        ServiceHostBase serviceHostBase)
      {
          foreach (var ed in
              serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(cd => cd.Endpoints))
          {
              InstanceProvider.ServiceType = serviceDescription.ServiceType;
              ed.DispatchRuntime.InstanceProvider = InstanceProvider;
          }
       }


       public void AddBindingParameters(
           ServiceDescription serviceDescription,
           ServiceHostBase serviceHostBase,
           Collection<ServiceEndpoint> endpoints,
           BindingParameterCollection bindingParameters) { }


       public void Validate(
           ServiceDescription serviceDescription,
           ServiceHostBase serviceHostBase) { }


       public void AddToHost(ServiceHost host)
       {
           if (_serviceHost != null)
               return;

           host.Description.Behaviors.Add(this);

           _serviceHost = host;
       }
    }
}

UnityInstanceProvider, a WCF Service Instance provider:

using System;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.Practices.Unity;

namespace Services.Host.Infrastructure
{
    public class UnityInstanceProvider : IInstanceProvider
    {
       public IUnityContainer Container { set; get; }


       public Type ServiceType { set; get; }


       public UnityInstanceProvider() : this(null) { }


       public UnityInstanceProvider(Type type)
       {
           ServiceType = type;
           Container = new UnityContainer();
       }


       public object GetInstance(
                       InstanceContext instanceContext,
                       Message message)
       {
           return Container.Resolve(ServiceType);
       }


       public object GetInstance(InstanceContext instanceContext)
       {
          return GetInstance(instanceContext, null);
       }


       public void ReleaseInstance(InstanceContext instanceContext, object instance)
       {
       }
   }
}

DefaultHostFactory that will take a Unity Configuration class as an argument (A class where all type is registered to the Unity Container):

using DependencyConfiguration;
using Services.Host.Infrastructure;

namespace HostFactory
{
    public class DefaultHostFactory : UnityServiceHostFactory
    {
        public DefaultHostFactory() : base(new WcfUnityConfiguration())
        {
        }
    }
}

Make sure to set the new Host Factory in the .svc file:

<%@ ServiceHost Language="C#" Factory="HostFactory.DefaultHostFactory"
Service="MyService, MyServices" %>

Unity, a helper class to Configure the Unity Container and also can be used to Resolve a type:

using System;
using Microsoft.Practices.Unity;

namespace Infrastructure.IocContainer
{

   public static class Unity
   {
      private static IUnityContainer _container;
      private static object _lock = new object();


      public static void Configure(IUnityConfiguration configuration)
      {
         if (configuration == null)
             throw new ArgumentNullException("configuration");

         lock (_lock)
         {
            if (_container != null)
                return;

            _container = new UnityContainer();
            configuration.Configure(_container);
         }
      }


      public static T Resolve<T>()
      {
         return Current.Resolve<T>();
      }


      public static IUnityContainer Current
      {
          get
          {
              if (_container == null)
                  throw new ApplicationException("You have to Configure the Unity first, you can do that by calling the Configure method");

              return _container;
          }
       }
   }
}

IUnityConfiguration:

using Microsoft.Practices.Unity;

namespace Infrastructure.IocContainer
{
    public interface IUnityConfiguration
    {
        void Configure(IUnityContainer container);
    }
}

WcfUnityConfiguration, a separate class to put all registration of types into the Unity container:

using Infrastructure.IocContainer;
using Microsoft.Practices.Unity;

namespace DependencyConfiguration
{
    public class WcfUnityConfiguration : IUnityConfiguration
    {
        public void Configure(IUnityContainer container)
        {
            container.RegisterType<IFoo, Foo>();
            //...
        }
    }
}

Share: twitter | facebook   Action: used | fork | flag

.net4

Mark '.net4' tag as 'like'

Mark '.net4' tag as 'ignore'

c#

Mark 'c#' tag as 'like'

Mark 'c#' tag as 'ignore'

dependency-injection

Mark 'dependency-injection' tag as 'like'

Mark 'dependency-injection' tag as 'ignore'

unity

Mark 'unity' tag as 'like'

Mark 'unity' tag as 'ignore'

wcf

Mark 'wcf' tag as 'like'

Mark 'wcf' tag as 'ignore'


 @fredrikn "I'm the master"
3.11k
September 29, 2010 2:24 PM
edited September 29, 2010 2:24 PM

Fork

 WCF Service factory for using Microsoft Unity 2.0 to create an instance of a Service -  @fredrikn Wednesday 29, 2010 2:24 PM


0 Feedback


You must log in before you can give any feedback


2 Discussion(s)

Newest Oldest
0

I found this useful, but I found that if my service implements IDisposable, the Dispose method isn't getting called.

UnityInstanceProvider.ReleaseInstance should probably check if the instance object is IDisposable and call Dispose?

thanks!

link | flag  | Reply

 codeblast
11
Tuesday 17, 2011 1:49 PM

0

Thanks for a great article. I have implemented in a WCF service hosted in IIS.

I have one problem, the DefaultHostFactory is not called 'prior' to the WCF service constructor which is what I need in order to be able to . I am trying to use Enterprise Library's Unity Dependency injection to to resolve two dependencies passed in to the constructor. Strangely, if I use only one of the parameters, the dependency is resolved (even though the DefaultHostFactory is not called). It fails when I try with two parametes.

The concrete class implementing IInstanceProvider is called prior to the constructor running.

Is there something in the config file that I need to add to ensure that the DefaultHostFactory is instantiated and then the IUnityConfiguration.Configure method is called.

I have configured it as per your example in the svc file. I am using Enterprise Library 5.0; .Net framework 4.0

Thanks again.

Regards

Grant

link | flag  | Reply

 SuttyHoo
10
Wednesday 22, 2011 2:19 PM


You must log in before you can post a comment

Squeed
Made by: Fredrik Normén 2010