2012-10-31 74 views
1

我正在使用Provider pattern和Unity。如何在提供程序實現具有依賴性時使用Unity與提供程序模式

這是典型的提供者實現。我有SomeProvider作爲具有抽象方法的抽象基礎提供者以及用於實例化defaultProvider的邏輯。

public abstract class SomeProvider : ProviderBase 
{ 
    #region provider boilerplate 

    private const string PROVIDER_NAME = "someProvider"; 
    private static volatile SomeProvider defaultProvider = null; 
    public static SomeProvider Provider 
    { 
     get { return defaultProvider; } 
    } 
    private static object providerLockObject = new object(); 
    static SomeProvider() 
    { 
     LoadProvider(); 
    } 
    private static void LoadProvider() 
    { 
     if (defaultProvider == null) 
     { 
      lock (providerLockObject) 
      { 
       if (defaultProvider == null) 
       { 
        // exception handling omitted for brevity 
        var section = ConfigurationManager.GetSection(PROVIDER_NAME) 
         as BaseProviderConfigurationSection; 
        defaultProvider = ProvidersHelper.InstantiateProvider(
         section.Providers[section.DefaultProvider], typeof(SomeProvider)) as SomeProvider; 
       } 
      } 
     } 
    } 

    protected SomeProvider() { } 

    #endregion 

    #region abstract methods 

    public abstract bool DoSomething(); 

    #endregion 
} 

這是實現SomeProviderASomeProvider。請注意,ASomeProvider具有依賴性ADependencySomeProvider沒有。

public class ASomeProvider : SomeProvider 
{ 
    #region provider boilerplate 

    private string name; 
    public override string Name 
    { 
     get { return name; } 
    } 

    public override void Initialize(string name, NameValueCollection config) 
    { 
     this.name = name; 
     base.Initialize(name, config); 
    } 

    #endregion 

    // Provider pattern needs parameterless ctor and calls this 
    public ASomeProvider() { } 
    // constructor injection 
    public ASomeProvider(ADependency aDependency) 
    { 
     this.ADependency = aDependency; 
    } 

    [Dependency] 
    public SomeDependency ADependency { get; set; } 

    #region methods 

    public override void DoSomething() 
    { 
     // do something 
    } 

    #endregion 
} 

class SomeDependency {} 

我使用ASomeProvider在業務層如下:

public class SomeBusinessLayer 
{ 
    public SomeProvider someProvider; 

    public SomeBusinessLayer(SomeProvider someProvider) 
    { 
     this.someProvider = someProvider; 
    } 

    #region methods 
    public bool DoSomethingWrapper() 
    { 
     return someProvider.DoSomething(); 
    } 
    #endregion 
} 

我有BusinessLayerFactory工廠連接最多使用Unity對象和返回對象如下:

public static class BusinessLayerFactory 
{ 
    private static UnityContainer container; 

    private static void WireUp() 
    { 
     container = new UnityContainer(); 

     container.RegisterInstance(SomeProvider.Provider); 
     container.RegisterInstance(new SomeDependency()); 
     container.RegisterType<SomeBusinessLayer>(new ContainerControlledLifetimeManager()); 
    } 
    public static SomeBusinessLayer SomeBusinessLayer_Unity 
    { 
     get 
     { 
      return container.Resolve<SomeBusinessLayer>(); 
     } 
    } 
    public static SomeBusinessLayer SomeBusinessLayer_Self() 
    { 
     var asomeProvider = SomeProvider.Provider as ASomeProvider; 
     if (asomeProvider != null && asomeProvider.ADependency == null) 
      asomeProvider.ADependency = new ADependency(); 
     return new SomeBusinessLayer(SomeProvider.Provider); 
    } 
} 

的我有的問題是,當我決心得到SomeBusinessLayer時,someProvider將其依賴關係ADependency設爲空。

var someBusinessLayer = BusinessLayerFactory.SomeBusinessLayer_Unity; 

((ASomeProvider)someBusinessLayer.someProvider).ADependencynull

原因是Provider模式使用助手方法ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type type)來實例化默認提供程序,而不是通過Unity的Resolve<T>()方法。

我可以想象這樣做沒有統一如SomeBusinessLayer_Self其中我新ADependency如果null但只是想知道如何以及如何統一處理這一點。

方法注射或Ctor注射對我來說很好。

如何解決這個問題並讓Unity和Provider模式一起工作?我使用Unity的主要原因是在工廠連線對象。

我沒有使用MVC。

UPDATE:

要解決這個問題:。 hat-tip到@seth-flowers

我想不通沒有明確演員的方式container.BuildUp<ASomeProvider>(aSomeProvider)。在BusinessLayerFactory.WireUp方法

container.RegisterInstance(new SomeDependency()); 

//this does not build up the object with dependency 
container.BuildUp(SomeProvider.Provider); 
//this works and does build up 
var aSomeProvider = SomeProvider.Provider as ASomeProvider; 
if(aSomeProvider != null) 
    container.BuildUp<ASomeProvider>(aSomeProvider); 
//compile error 
container.BuildUp<ASomeProvider>(SomeProvider.Provider); 

container.RegisterInstance(SomeProvider.Provider); 

container.RegisterType<SomeBusinessService>(new ContainerControlledLifetimeManager()); 
+0

鏈接的文章沒有說明你需要一個公共無參數的構造函數。刪除不需要的構造函數將使您不必配置Unity來解析特定的InjectedConstructor。 – Tejs

+0

@Tejs,'ProvidersHelper.InstantiateProvider(settings,type)'方法需要一個無參數的ctor否則拋出一個異常。在第二部分評論中你不明白你的意思。任何示例? – hIpPy

回答

1

你不能使用UnityContainer.BuildUp,以充實您SomeProvider.Provider實例的依賴?你的對象仍然會通過你的提供者實現來構造,但是通過統一可以實現依賴注入。

例如:

private static void WireUp() 
{ 
    container = new UnityContainer(); 

    container.RegisterInstance(SomeProvider.Provider); 
    container.RegisterInstance(new SomeDependency()); 
    container.RegisterType<SomeBusinessLayer>(
     new ContainerControlledLifetimeManager()); 

    container.BuildUp<ASomeProvider>(SomeProvider.Provider as ASomeProvider); 
} 

BuildUp狀態的文檔如下:當你不控制的 實例的製作(ASP.NET頁面或

此方法非常有用例如通過XAML創建的對象),但您仍然需要執行屬性和其他注入。

+0

'BuildUp'的確幫我解決了這個問題。我正在更新這個問題。我不知道是否有更好的方法。 – hIpPy

+0

哎呀 - 我正在這麼做:)。更新了答案。 –

+0

找到了更好的方法。我擺脫了'提供者'模式,並完全使用'Unity'。由於'Unity'管理對象的創建,我不必使用'BuildUp'方法。 – hIpPy

相關問題