WCF поддерживает Конструктор Injection , но вам нужно прыгнуть через несколько обручей, чтобы добраться туда. Ключ лежит в написании пользовательского ServiceHostFactory. Хотя он также должен иметь конструктор по умолчанию, вы можете использовать его, чтобы связать все правильные поведения.
В качестве примера я недавно написал тот, который использует Castle Windsor для подключения зависимостей для реализации сервиса. Реализация CreateServiceHost просто делает это:
return new WindsorServiceHost(this.container, serviceType, baseAddresses);
где this.container
- это настроенный IWindsorContainer.
WindsorServiceHost выглядит так:
public class WindsorServiceHost : ServiceHost
{
public WindsorServiceHost(IWindsorContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
foreach (var cd in this.ImplementedContracts.Values)
{
cd.Behaviors.Add(new WindsorInstanceProvider(container));
}
}
}
и WindsorInstanceProvider выглядит следующим образом:
public class WindsorInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly IWindsorContainer container;
public WindsorInstanceProvider(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
var serviceType = instanceContext.Host.Description.ServiceType;
return this.container.Resolve(serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
this.container.Release(instance);
}
#endregion
#region IContractBehavior Members
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)
{
}
#endregion
}
Это может выглядеть много, но обратите внимание, что это универсальный код многократного использования, который имеет довольно низкую цикломатическую сложность.
Вы можете следовать той же идиоме кодирования, чтобы внедрить Dependency Injection с другим DI-контейнером или с помощью DI Бедного.
Вот более старая запись этой идиомы, в которой используется DI Бедного.