我正在构建一个 POC,旨在演示如何使用 Unity 从 WCF 服务中构建依赖层次结构,并使应用程序中的所有程序集完全松散耦合。
我所做的是创建以下类库:
数据访问层:
- 一个带有存储库接口的程序集。
- 一个实现了这个接口的程序集,它假装访问一个数据库。
- 一个实现了这个接口的程序集,它假装访问 XML 文档。
业务层:
- 一个带有业务对象接口的程序集。
- 一个实现了此接口的程序集,它在其构造函数中接收存储库接口。
服务层:
- 一个带有服务接口的组件。
- 一个实现了此接口的程序集,它在其构造函数上接收业务对象接口。
最后,我创建了一个包含服务主机工厂、服务主机和实例提供程序的程序集,它将负责创建依赖关系层次结构。代码如下所示:
public class UnityServiceHostFactory : ServiceHostFactory
{
private readonly UnityContainer _container;
public UnityServiceHostFactory()
{
_container = new UnityContainer();
new ContainerConfigurator().Configure(_container);
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new UnityServiceHost(_container, serviceType, baseAddresses);
}
}
public class ContainerConfigurator
{
public void Configure(UnityContainer container)
{
container.RegisterType<IInvoiceRepository, InvoiceRepository>("dbInvoiceRepository");
container.RegisterType<IInvoiceRepository, XmlInvoice>("xmlInvoiceRepository");
container.RegisterType<IInvoiceFinder, InvoiceFinder>();
}
}
public class UnityServiceHost : ServiceHost
{
public UnityServiceHost(UnityContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if(container == null) throw new ArgumentNullException("container");
var contracts = ImplementedContracts.Values;
foreach (var c in contracts)
{
var instanceProvider = new UnityInstanceProvider(container, serviceType);
c.Behaviors.Add(instanceProvider);
}
}
}
public class UnityInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly UnityContainer _container;
private readonly Type _serviceType;
public UnityInstanceProvider(UnityContainer container, Type serviceType)
{
if (container == null) throw new ArgumentNullException("container");
if (serviceType == null) throw new ArgumentNullException("serviceType");
_container = container;
_serviceType = serviceType;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return _container.Resolve(_serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
_container.Teardown(instance);
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.InstanceProvider = this;
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
}
我正在使用控制台应用程序对此进行测试,我实例化了服务代理并调用了它的方法,但是由于两个注册都被命名为 Unity 不知道要实例化哪一个。如果我从其中任何一个中删除名称,它将成功解决。
基本上我希望能够做这样的事情:
static void Main(string[] args)
{
//First call, want it to resolve to the InvoiceRepository concrete type
//new InvoiceService(new InvoiceFinder(new InvoiceRepository))
var invoiceService1 = new InvoiceProxy();
var response1 = invoiceService1.GetSumarizedInvoiceBy(new InvoiceRequest(1));
//Second call, want it to resolve to the XmlInvoice concrete type
//new InvoiceService(new InvoiceFinder(new XmlInvoice))
var invoiceService2 = new InvoiceProxy();
var response2 = invoiceService2.GetSumarizedInvoiceBy(new InvoiceRequest(2));
}
请注意 invoiceService1 和 invoiceService2 如何是同一服务的两个不同实例,但其自身依赖项中的依赖项对两者的解析方式不同。
当我实例化服务代理或调用其方法时,我必须做什么才能告诉 Unity 要实例化哪个存储库?
谢谢你的帮助。