7

問題:使用Autofac依賴創建一個類的實例

假設類:

public class MyAwesomeClass 
{ 
    private IDependCls _dependCls; 
    public MyAwesomeClass(IDependCls dependCls) 
    { 
     _dependCls = dependCls; 
    } 

} 

而且別的地方我需要得到這個類的一個實例,像這樣:

public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     //... 
     // AwesomeStuff 
     //... 

     var GetErDone = new MyAwesomeClass(); // PROBLEM! No constructor with 0 arguements 
    } 
} 

問題是,我是不是

建議的解決方案1:

A)必須製作一個額外的構造函數來解析依賴關係嗎?例如:

public MyAwesomeClass() // new constructor 
    { 
     _dependCls = DependencyResolver.Current.GetService<IDependCls>(); 
    } 


public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     var GetErDone = new MyAwesomeClass(); // IT WORKS!! 
    } 
} 

提議的解決方案2:

B)使用內部AwesomeMethod分解前右var GetErDone

public class SomewhereElse 
{ 
    public void AwesomeMethod() 
    { 
     var depCls = _dependCls = DependencyResolver.Current.GetService<IDependCls>(); 
     var GetErDone = new MyAwesomeClass(depCls); // IT WORKS!! 
    } 
} 

Autofac溶液?

C)其他一些Autofac方式?

尋找最佳實踐,以及儘可能好的Autofac解決方案。我認爲第一種方式是最糟糕的,因爲可選的依賴可能導致很多混亂。

摘要:

我如何獲得一個new MyAwesomeClass()MyAwesomeClass有依賴性?

+0

你真的是_optional_當你說了嗎?如果確實是可選的,那麼您可能需要考慮財產注入。如果沒有,並且你的ctor由於太多的依賴關係而混亂,也許你的班級做得太多了(另請參閱[這個答案](http://stackoverflow.com/a/2420245/1282778))。 –

+0

我沒有關於構造函數混亂的問題,而不是創建需要構造函數注入的類的實例。 –

+0

感謝您不要發佈解決方案答案。不像任何其他人有這個問題.../s –

回答

7

看看Composition Root模式。

你是對的,拉起依賴分辨率只有把問題移到另一個地方。但是,如果您繼續在對象圖中向上移動它,則會達到應用程序的入口點。在那裏你將組成你的對象圖。

將此與Service Locator anti-pattern(在您的案例中,在客戶端類中使用DependencyResolver)相比較,您將看到組合根是一種優越的解決方案。

+0

感謝您的回覆。 +1,因爲你確實掌握了這個概念,並感謝你的文章。所以我想這會不可避免地發生?我將更多地閱讀這種方法,但我認爲,您稱之爲的實際組成根應該是綁定本身的聲明。否則,你會破壞單一責任和關注分離規則。 –

+0

是的,組合根被抽象地定義爲「位置」,您可以將它分成幾個類,但重要的是它們包含在同一個程序集中。馬克西曼,該文章的作者寫道[偉大的書(http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501)約DI BTW。 –

+1

@Mihalis - 您是否曾經使用Composition Root模式或其他方式獲得滿意的解決方案。你的示例代碼很容易遵循,我想看看第三種解決方案的代碼 - thans –

0

如果你想通過Autofac自動解決的實例,你只能從這個

  • 進樣在你的類
  • 進樣的財產,構造選擇使用

    var builder = new ContainerBuilder();

    builder.RegisterType<Foo>().PropertiesAutowired();

  • 個使用由DependencyResolver.Current.GetService<IFoo>();

+0

我正在使用構造函數注入,但我詢問創建該類的實例的實際過程。 –

+0

你是指創建該類的一個實例的過程是什麼?你想實例化什麼類?你到底想做什麼? Prodide更多信息 –

+0

請參閱第二個灰色塊。如果我按原樣使用代碼,我會遇到問題(當然)。然後,我提出兩個我不喜歡的解決方案,並要求提供第三個解決方案 - 或者確認我建議的2個解決方案之一是標準實踐。我會更新的答案實際上包括我的解決方案給你看 –

0

全球接入在包含MyAwesomeMethod類採取MyAwesomeClass作爲構造依賴。 Autofac將負責實例化。

+0

肯定的,但這種正義之舉的問題,一類高起來,這是我真正的位置。如果我想創建一個包含「MyAwesomeMethod」類的實例,該怎麼辦? –

0

首先除了構造函數注入外,還可以使用property injectionmethod injection。然而構造函數注入是最常見和最快速的方法,所以我建議堅持下去。

您需要做的第二件事是在Autofac容器中註冊您的MyAwesomeClass及其依賴關係,他們在主頁上有一些不錯的examples

而最後一件事 - 你不應該直接創建的MyAwesomeClass實例 - 使用Autofac代替。這裏是一個更新的例子:

public void AwesomeMethod() 
{ 
    //... 
    // AwesomeStuff 
    //... 

    var GetErDone = DependencyResolver.Current.GetService<MyAwesomeClass>(); 
} 
+0

這會創建一個新的實例還是已經註冊的服務? – theusguy