Есть ли у кого четкая инструкция по настройке Ninject в WCF? был googling, но я не вижу никаких обновленных рекомендаций о том, как использовать Ninject в WCF.
Настройка Ninject для WCF
Ответ 1
Использование NInject с WCF аналогично использованию любого другого контейнера DI. Для этого вам необходимо использовать 3 точки расширяемости WCF: InstanceProvider
, ServiceHost
и ServiceHostFactory
.
Пользовательский 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
. В приведенном ниже коде представлены реализации ServiceHost
и ServiceHostFactory
.
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
.
Настройка завершена в этот момент. Все, что вам нужно сделать, это создать службу WCF, которая имеет зависимость от IDummyDependency
. Кроме того, не забудьте установить атрибут Factory
в файле svc, как показано ниже (щелкните правой кнопкой мыши на файле svc, затем "View Markup" ):
<%@ ServiceHost Language="C#" Debug="true" Service="Service.DummyService" Factory="Service.NInjectServiceHostFactory" %>
Надеюсь, это поможет. Кроме того, я думаю, что NInject предлагает некоторые реализации для этого из коробки в NInject.Extensions.Wcf.dll.