2013-03-21 8 views
0

我正在構建一個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在實例化服務代理或調用它的方法時要實例化哪個存儲庫?

感謝您的幫助。

回答

0

將您給Unity的名稱傳遞給RegisterType <>()調用Resolve <>()。

Resolving an Object by Type and Registration Name

// Create container and register types 
IUnityContainer myContainer = new UnityContainer(); 
myContainer.RegisterType(typeof(MyServiceBase), typeof(DataService), "Data"); 
myContainer.RegisterType(typeof(MyServiceBase), typeof(LoggingService), "Logging"); 

// Retrieve an instance of each type 
MyServiceBase myDataService = (MyServiceBase)myContainer.Resolve(typeof(MyServiceBase), "Data"); 

您使用的是通用的擴展方法等效於這個例子。

+0

謝謝ErnieL。看起來,這是我可能需要的整體解決方案,但本身並不是我正在尋找的東西。我添加了一段客戶端代碼來說明我想如何使用它。 – 2013-03-21 21:43:41

相關問題