为WCF设置Ninject

11

有没有人有关于如何在WCF中设置Ninject的清晰指导?我已经Google了一圈,但是我没有看到任何关于如何在WCF中使用Ninject的更新指南。


9
在 Stack Overflow 上提问变得越来越困难了。每个人都认为自己很聪明,也期望你很聪明。 - Romeo
1个回答

16

使用NInject与WCF的方法与使用其他依赖注入容器相同。为此,您需要使用3个WCF可扩展性点:InstanceProviderServiceHostServiceHostFactory

自定义的InstanceProvider将用于通过使用带参数的构造函数创建服务实例。以下是代码示例:

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)
    {
    }
}

然后将此自定义实例提供程序应用于ServiceHost类中的每个契约。这是通过使用契约行为完成的。这就是为什么实例提供程序还要实现IContractBehavior的原因。您可以在ApplyDispatchBehavior方法中看到我们应用实例提供程序。下面的代码呈现了ServiceHostServiceHostFactory实现。

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));
        }
    }
}

你可以看到,在ServiceHost构造函数内部,我们遍历所有实现的契约并应用我们需要的行为。在我们的情况下,这是NInjectInstanceProvider

自定义的ServiceHostFactory需要创建DI容器并填充映射。我们然后覆盖CreateServiceHost方法以提供我们的自定义ServiceHost实现。

此时设置已经完成。您只需要创建一个具有对IDummyDependency的依赖项的WCF服务。还要不要忘记像下面这样设置svc文件中的Factory属性(右键单击svc文件,然后选择“查看标记”):

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

希望这能帮到您。此外,我认为NInject在NInject.Extensions.Wcf.dll中提供了一些开箱即用的实现。


嗨@flo_badea,这些代码有示例项目吗?你能分享一下吗? - Romeo
2
您可以在 https://onedrive.live.com/?cid=3665BE6DBD76EBA7&id=3665BE6DBD76EBA7!355 获取一个示例。 - flo_badea
另外一种方法可以在这里找到:https://dev59.com/8XA75IYBdhLWcg3wH1JB#11734620 - juFo
你可以在这里找到Github代码 https://github.com/ninject/Ninject.Extensions.Wcf - Fed Liskov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接