Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WCF Rest service Dependecy injection with Unity and EF4 CodeFirst

0.00/5 (No votes)
21 Mar 2011 1  
Assuming you already have your domain model and repositories implemented and unity wired (if you are missing this part, let me know and i'll add the

This articles was originally at wiki.asp.net but has now been given a new home on CodeProject. Editing rights for this article has been set at Bronze or above, so please go in and edit and update this article to keep it fresh and relevant.

Assuming you already have your domain model and repositories implemented and unity wired (if you are missing this part, let me know and i'll add the full stack on a blog), traditionally being consumed by a asp.net MVC3 application, I have added a service assembly that pretty much implements the basic business logic on the repository querying (i leave the heavy processes to a fsharp component) . this would look like the below:

 

    public interface IExampleService
    {
        IEnumerable<Example> GetAll();       
    }
 
   public class ExampleService : IExampleService
   {
       private readonly IExampleRepository ExampleRepository;
       private readonly IUnitOfWork unitOfWork;
       public ConfigService(IConfigRepository exampleRepository, IUnitOfWork unitOfWork)
       {
           this.ExampleRepository = exampleRepository;
           this.unitOfWork = unitOfWork;
       }
 
       public IEnumerable<Config> GetAll()
       {
           var categories = ConfigRepository.GetAll();
           return categories;
       }
    }
 
 
 
Now, let's say you badly want to wire this to wcf with unity.
That's how you do it. Create a new class file and dump the code below:
 
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.ObjectModel;
 
namespace Example.Rest.Helpers
{
    public class IoC
    {
        public class UnityWebServiceHost : WebServiceHost
        {
            protected IUnityContainer _container;
 
            public UnityWebServiceHost()
            {
            }
 
            public UnityWebServiceHost(object singletonInstance, params Uri[] baseAddresses)
                : base(singletonInstance, baseAddresses)
            {
            }
 
            public UnityWebServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
                : base(serviceType, baseAddresses)
            {
                if (container == null)
                {
                    throw new ArgumentNullException("container");
                }
                _container = container;
            }
 
            protected override void OnOpening()
            {
                Description.Behaviors.Add(new UnityServiceBehaviour(_container));
                base.OnOpening();
            }
        }
 
        public class UnityInstanceProvider : IInstanceProvider
        {
            private readonly Type _serviceType;
            private readonly IUnityContainer _container;
 
            public UnityInstanceProvider(IUnityContainer container, Type serviceType)
            {
                _serviceType = serviceType;
                _container = container;
            }
 
 
            public object GetInstance(InstanceContext instanceContext)
            {
                return GetInstance(instanceContext, null);
            }
 
            public object GetInstance(InstanceContext instanceContext, Message message)
            {
                return _container.Resolve(_serviceType);
            }
 
            public void ReleaseInstance(InstanceContext instanceContext, object instance)
            {
            }
 
        }
 
        public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
        {
            public override object GetValue()
            {
                return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
            }
            public override void RemoveValue()
            {
                HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
            }
            public override void SetValue(object newValue)
            {
                HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
            }
            public void Dispose()
            {
                RemoveValue();
            }
 
        }
 
        public class UnityServiceBehaviour : IServiceBehavior
        {
            private readonly IUnityContainer _container;
 
            public UnityServiceBehaviour(IUnityContainer container)
            {
                _container = container;
            }
 
            public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                foreach (var endpointDispatcher in
                    serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(
                        channelDispatcher => channelDispatcher.Endpoints))
                {
                    endpointDispatcher.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(_container, serviceDescription.ServiceType);
                }
            }
 
            public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
                                             Collection<ServiceEndpoint> endpoints,
                                             BindingParameterCollection bindingParameters)
            {
            }
 
            public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
            }
        }
    }
}
 
Okay, Let's setup a wcf rest service:
 
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class ExampleApi
    {
        private readonly IExampleService exampleService;
 
        public ExampleApi(IExampleService exampleService)
  {
   this.exampleService = exampleService;      
  }
 
        public exampleApi()
        {           
        }
 
        [WebGet(UriTemplate = "")]
        public IEnumerable<Example> GetAll()
        {
            var examples = exampleService.GetAll();        
   return examples;  
        }
 
     }
 
Now, insure your WCFrest app global.asax file looks like the following, so we use our custom UnityServiceHostFactory and register our dependencies:
 
public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();          
        }
 
        private void RegisterRoutes()
        {
            RouteTable.Routes.Add(new ServiceRoute("ExampleApi", new UnityServiceHostFactory(), typeof(ExampleApi)));
        }
           
        private static void RegisterTypes(IUnityContainer container)
        {
            container.RegisterType<IDatabaseFactory, DatabaseFactory>(new IoC.HttpContextLifetimeManager<IDatabaseFactory>());
            container.RegisterType<IUnitOfWork, UnitOfWork>(new IoC.HttpContextLifetimeManager<IUnitOfWork>());
 
            // repositories
            container.RegisterType<IExampleRepository, ExampleRepository>(new IoC.HttpContextLifetimeManager<IExampleRepository>());
 
            // services
            container.RegisterType<IExampleService, ExampleService>(new IoC.HttpContextLifetimeManager<IExampleService>());
        }
 
        public class UnityServiceHostFactory : WebServiceHostFactory
        {
            protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
            {
                var container = new UnityContainer();
 
                RegisterTypes(container);
 
                return new IoC.UnityWebServiceHost(container, serviceType, baseAddresses);
            }
        }
    }
 
 
That's all folks.
 
 
 
 
 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here