Click here to Skip to main content
15,881,413 members
Articles / Read-only
Article

WCF Rest service Dependecy injection with Unity and EF4 CodeFirst

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
11 Oct 2013CPOL3 min read 11.1K   1   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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
The ASP.NET Wiki was started by Scott Hanselman in February of 2008. The idea is that folks spend a lot of time trolling the blogs, googlinglive-searching for answers to common "How To" questions. There's piles of fantastic community-created and MSFT-created content out there, but if it's not found by a search engine and the right combination of keywords, it's often lost.

The ASP.NET Wiki articles moved to CodeProject in October 2013 and will live on, loved, protected and updated by the community.
This is a Collaborative Group

755 members

Comments and Discussions

 
QuestionKindly add domain Model and Repositories to your article Pin
Member 1060656211-Dec-14 5:25
Member 1060656211-Dec-14 5:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.