c# - 为 WCF 设置 Ninject

标签 c# wcf ninject ninject-extensions

<分区>

有没有人对如何在 WCF 中设置 Ninject 有明确的说明?一直在谷歌搜索,但我看不到任何关于如何在 WCF 中使用 Ninject 的更新指南。

最佳答案

将 NInject 与 WCF 一起使用与使用任何其他 DI 容器相同。为此,您需要使用 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 类中的每个契约(Contract)。这是通过使用契约行为来完成的。这就是实例提供程序还实现 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 中为此提供了一些开箱即用的实现。

关于c# - 为 WCF 设置 Ninject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25102582/

相关文章:

wcf - AddressAccessDeniedException "Your process does not have access rights to this namespace"单元测试 WCF 服务时

inversion-of-control - 使用 Ninject 的装饰器如何进行绑定(bind)?

log4net - Ninject 2、日志记录和 WebForms

c# - 并行处理一组 url 并返回一个 IEnumerable

c# - WCF服务调用

c# - SQLite,在我的表中插入变量(c# 控制台应用程序)

c# - 如何在 C# 中将命名空间添加到 soap 信封

c# - ASP.NET Web API 2 和 Ninject - 发现不明确的匹配项

c# - xmlns :dc mean in C# WPF? 是什么

c# - 有条件地将不同的 json 属性反序列化为相同的模型属性