2013-07-31 33 views
0

我有第三方庫返回類實例。這是我的cotrol,但我想用Unity在其公共財產inyect。由於我不能將DependecyAttribute添加到其屬性中,因爲該類不是部分的,也不是inheritalbe,所以我想知道是否可以使用Unity XML配置來執行檢查。沒有依賴屬性的Unity BuildUp

是否可以使用Unity's XML配置來配置構建依賴關係?如果答案是肯定的。如何配置XML來做到這一點?

我已經試過:如果Unity ResolveThidPartyObj買不BuilUp(服務屬性空引用)工作

<register type="IService" mapTo="Service"> <!--Service has public constructor--> 
</register> 

<!--ThirdPartyObj has no interface and no public constructor--> 
<register type="ThirdPartyObj " mapTo="ThirdPartyObj"> 
    <!-- Inject the property "Service" --> 
    <property name="Service" /> //type of the property is IService 
</register> 

這個配置將工作,不能ResolveThirdPartyObj因爲沒有公開的構造函數。

什麼,我想archieve簡單的例子:

IUnityContainer uc = New UnityContainer() //create container 
container.LoadConfiguration() // load from XML config 
ThirdPartyObj foo = ThirdPartyLibrary.getFooInstace() //get third party instance 
container.BuildUp(foo.getType, foo) //inyect dependencies 
Console.WriteLine(foo.Service.getServiceMessage) 

回答

1

根據您發佈的代碼,應該沒有問題。

我創建了2個項目:一個控制檯應用程序和一個名爲ThirdPartyLibrary的類庫。

的ThirdPartyLibrary包括以下內容(從貼碼外推):

namespace ThirdPartyLibrary 
{ 
    public interface IService 
    { 
     string GetServiceMessage { get; } 
    } 

    public class Service : IService 
    { 
     public Service() { } 

     public string GetServiceMessage 
     { 
      get { return "The message!"; } 
     } 
    } 

    public static class ThirdPartyLibrary 
    { 
     public static ThirdPartyObj GetFooInstance() 
     { 
      return new ThirdPartyObj(); 
     } 
    } 

    public interface IThirdPartyObj { } 
    public class ThirdPartyObj : IThirdPartyObj 
    { 
     internal ThirdPartyObj() { } 
     public IService Service { get; set; } 
    } 
} 

XML配置是這樣的:

<?xml version="1.0"?> 
<configuration> 
    <configSections> 
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> 
    </configSections> 

    <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 

    <container> 
     <register type="ThirdPartyLibrary.IService, ThirdPartyLibrary" mapTo="ThirdPartyLibrary.Service, ThirdPartyLibrary"> 
     </register> 

     <register type="ThirdPartyLibrary.IThirdPartyObj, ThirdPartyLibrary" mapTo="ThirdPartyLibrary.ThirdPartyObj, ThirdPartyLibrary"> 
     <!-- Inject the property "Service" --> 
     <property name="Service" /> 
     </register> 
    </container> 

    </unity> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/> 
    </startup> 
</configuration> 

和控制檯應用程序是:

class Program 
{ 
    static void Main(string[] args) 
    { 
     IUnityContainer container = new UnityContainer(); //create container 
     container.LoadConfiguration(); // load from XML config 
     ThirdPartyObj foo = ThirdPartyLibrary.ThirdPartyLibrary.GetFooInstance(); //get third party instance 
     container.BuildUp(foo.GetType(), foo); //inyect dependencies 
     Console.WriteLine(foo.Service.GetServiceMessage); 
    } 
} 

這可以正常工作,並按預期輸出The message!。也許,確切的情況是不一樣的你張貼(我假設虛構)的例子或其他東西沒有正確配置?

+0

謝謝Tuzo!至少我有確認我正確的方式。必須是沒有很好地confjured因爲我想你的例子和foo.Service在我的調試器中爲空。這很奇怪。在接受你的答案之前,給我一些時間在我的配置中查找錯誤。 – jlvaquero

+0

我剛剛創建了一個新項目,複製粘貼我的代碼,我的配置和一直運行良好。 – jlvaquero

1

創建這樣的包裝,是團結友好:

public interface IThirdpartyWrapper 
{ 
    ThirdpartyObj ConfiguredObject{get;} 
} 
public class ThirdpartyWrapper:IThirdpartyWrapper 
{ 
    private ThirdpartyObject _thirdPartyObject; 
    public ThirdpartyWrapper(IService myService) 
    { 
     _thirdPartyObject=ThirdPartyLibrary.getFooInstance(); 
     _thirdPartyObject.Service=myService; 
    } 
    public ThirdpartyObj ConfiguredObject 
    { 
     get{return _thirdPartyObject;} 
    } 

} 

現在我們有一個團結友好類

統一的XML配置:

<register type="IService" mapTo="Service"> <!--Service has public constructor--> 
</register> 

<!--ThirdPartyObj has no interface and no public constructor--> 
<register type="IThirdpartyWrapper" mapTo="IThirdpartyWrapper"> 
</register> 

當我執行以下操作:

var wrapper=_container.Resolve<IThirdpartyWrapper>(); 
var configuredObject=wrapper.ConfiguredObject; 

包裝器實例化第三方對象的副本,然後噴射服務到相應的屬性(或可以通過一個方法調用被傳遞在等)。

這不會佔用太多代碼,可以進行單元測試,並且可以滿足您的需求。

+0

嗨,謝謝你的答案,但我想要的是在ThirdPartyObj中服務而不是服務中的TridPartyObj。在我的最後一段代碼中獲取一個掠奪來檢查我想要的結果。 – jlvaquero

+0

固定。反轉DI但仍然適用。只需創建一個包裝,使DI不友好的代碼DI友好。在上面的例子中,我們將IService實例注入包裝器並將其傳遞給第三方對象。 –