Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setup Ninject for WCF [closed]

Does anyone have a clear instruction on how to setup Ninject in WCF? been googling around but I cant see any updated guidelines on how to use Ninject in WCF.

like image 936
Romeo Avatar asked Aug 03 '14 07:08

Romeo


1 Answers

Using NInject with WCF is the same as using any other DI container. To do this you need to use 3 WCF extensibility points: InstanceProvider, ServiceHost and ServiceHostFactory.

The custom InstanceProvider will be used to create service instances by using a constructor with parameters. The code can be seen below.

public class NInjectInstanceProvider : IInstanceProvider, IContractBehavior
{
    private readonly IKernel kernel;

    public NInjectInstanceProvider(IKernel kernel)
    {
        if (kernel == null) throw new ArgumentNullException("kernel");
        this.kernel = kernel;
    }

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        //delegate to GetInstance(InstanceContext)
        return GetInstance(instanceContext);
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        //resolve the service instance
        return kernel.Get(instanceContext.Host.Description.ServiceType);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        kernel.Release(instance);
    }

    public void AddBindingParameters(ContractDescription contractDescription, 
        ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ContractDescription contractDescription,
        ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription,
        ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.InstanceProvider = this;
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
    }
}

This custom instance provider is then applied to every contract in the ServiceHost class. This is done by using a contract behavior. This is why the instance provider also implements IContractBehavior. You can see that we apply the instance provider in the ApplyDispatchBehavior method. The code below presents the ServiceHost and ServiceHostFactory implementations.

public class NInjectServiceHostFactory : ServiceHostFactory
{
    private readonly IKernel kernel;

    public NInjectServiceHostFactory()
    {
        kernel = new StandardKernel();
        kernel.Bind<IDummyDependency>().To<DummyDepencency>();
        //add the rest of the mappings here
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new NInjectServiceHost(kernel, serviceType, baseAddresses);
    }
}

public class NInjectServiceHost : ServiceHost
{
    public NInjectServiceHost(IKernel kernel, Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        if (kernel == null) throw new ArgumentNullException("kernel");
        foreach (var cd in ImplementedContracts.Values)
        {
            cd.Behaviors.Add(new NInjectInstanceProvider(kernel));
        }
    }
}

You can see that inside the ServiceHost constructor we iterate over all implemented contracts and apply the behavior we need. In our case this is NInjectInstanceProvider.

The custom ServiceHostFactory is required in order to create the DI container and populate it with mappings. We then override the CreateServiceHost method in order to provide our custom ServiceHost implementation.

The setup is complete at this point. All you need to do is create a WCF service that has a dependency on IDummyDependency. Also, don't forget to set the Factory attribute in the svc file like below (right click on svc file, then "View Markup"):

<%@ ServiceHost Language="C#" Debug="true" Service="Service.DummyService" Factory="Service.NInjectServiceHostFactory" %>

Hope this helps. Also, I think NInject offers some implementations for this out of the box in NInject.Extensions.Wcf.dll.

like image 150
flo_badea Avatar answered Sep 23 '22 12:09

flo_badea