WCF hỗ trợ Constructor Injection, nhưng bạn phải nhảy qua một vài vòng để đến đó. Chìa khóa nằm trong văn bản một ServiceHostFactory tùy chỉnh. Trong khi đó, quá, phải có một constructor mặc định, bạn có thể sử dụng nó để dây lên tất cả các hành vi chính xác.
Ví dụ, gần đây tôi đã viết một trong đó sử dụng Castle Windsor để dây phụ thuộc cho việc thực hiện dịch vụ. Việc triển khai CreateServiceHost chỉ cần thực hiện điều này:
return new WindsorServiceHost(this.container, serviceType, baseAddresses);
nơi this.container
là IWindsorContainer được định cấu hình.
WindsorServiceHost trông như thế này:
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));
}
}
}
và WindsorInstanceProvider trông như thế này:
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
}
này có thể trông giống như rất nhiều, nhưng nhận thấy rằng đó là tái sử dụng, mã mục đích chung mà có một thay độ phức tạp chu kỳ thấp.
Bạn có thể thực hiện theo cùng một thành ngữ mã hóa để triển khai Dependency Injection với một DI Container khác hoặc bằng cách sử dụng DI của người nghèo.
Đây là một số older writeup của thành ngữ này sử dụng DI của người nghèo.
bạn có đang sử dụng thùng chứa IoC không? và nếu có cái nào? – Fabiano
Tôi chưa sử dụng IoC-container ở phía máy chủ. Lên kế hoạch giới thiệu một cái bây giờ. Đang sử dụng Unity ở phía máy khách (vì nó đi kèm với Prism), nhưng hãy xem xét sử dụng StructureMap trên máy chủ. Mở cho bất kỳ ai thực sự. – stiank81