我正在構建一個POC,旨在演示如何使用Unity在WCF服務中構建依賴關係層次結構,並將所有裝配保留在應用程序完全鬆散耦合。在單個自定義WCF服務主機工廠中使用Unity解析來自兩個不同裝配的Unity的相同接口
我所做的是創建以下類庫:
數據訪問層:
- 一個組件與存儲庫接口。
- 一個程序集,其中包含假裝訪問數據庫的此接口的實現。
- 一個實現此接口的程序集,它假裝訪問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)
{
}
}
我有一個控制檯應用程序測試此,我實例化服務代理,並調用它的方法,但由於兩者的登記被命名爲團結不知道實例化哪一個。如果我從其中任何一箇中刪除名稱,它會成功解決。
基本上我希望能夠做這樣的事情:
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在實例化服務代理或調用它的方法時要實例化哪個存儲庫?
感謝您的幫助。
謝謝ErnieL。看起來,這是我可能需要的整體解決方案,但本身並不是我正在尋找的東西。我添加了一段客戶端代碼來說明我想如何使用它。 – 2013-03-21 21:43:41