2009-11-17 105 views
6

長期讀者第一次作家在這裏。我目前正在從一個簡單的C#.NET應用程序轉換到使用Ninject到Castle Windsor的最新版本。溫莎城堡:多構造問題

在大多數情況下,轉換進展順利和容器的實施,完美執行。然而,我的存儲庫對象有一個小問題。

我有一個是用以下方式編碼的用戶信息庫對象:

public class UserRepository : IUserRepository { 
    public UserRepository(IObjectContext objectContext) { 
     // Check that the supplied arguments are valid. 
     Validate.Arguments.IsNotNull(objectContext, "objectContext"); 

     // Initialize the local fields. 
     ObjectContext = objectContext; 
    } 

    public UserRepository(IObjectContextFactory factory) 
     : this(factory.CreateObjectContext()) { 
    } 

    // ----------------------------------------------- 
    // Insert methods and properties... 
    // ----------------------------------------------- 
} 

要符合這個代碼,我已經安裝在我的應用程序的配置文件中的下列項目:

<castle> 
    <components> 
     <component id="objectContextFactory" lifestyle="custom" 
        customLifestyleType="Common.Infrastructure.PerWebRequestLifestyleManager, Common.Castle" 
        service="Project.DAL.Context.IObjectContextFactory, Project.DAL.LINQ" 
        type="project.DAL.Context.ObjectContextFactory, Project.DAL.LINQ"> 
     </component> 
     <component id="userRepository" lifestyle="custom" 
        customLifestyleType="Common.Infrastructure.PerWebRequestLifestyleManager, Common.Castle" 
        service="Project.BL.Repository.IUserRepository, Project.BL" 
        type="Project.BL.Repository.UserRepository, Project.BL.LINQ"> 
      <parameters> 
       <factory>${objectContextFactory}</factory> 
      </parameters> 
     </component> 
    </components> 
</castle> 

對我來說,一切看起來都應該如此。當我嘗試解析IObjectContextFactory服務的實例時,我檢索了一個ObjectContextFactory對象。我嘗試解決IUserRepository服務的實例時遇到了問題。我受到以下令人愉快的例外處理:

無法創建組件'userRepository',因爲它具有要滿足的依賴關係。 userRepository正在等待以下依賴性:

服務:

- SandCastle.DAL.Context.IObjectContext which was not registered.

我用盡了一切我可以在此想。所以,對你的讀者來說,我說:有什麼想法?

回答

7

這可能會被視爲一個bug(確實,像這樣的情況下,它是可以解決的),但它kindof通過一個設計功能。

溫莎嘗試匹配貪婪構造(具有最參數)它能夠滿足。

不過你的情況,也有具有參數(一)數量最多兩個構造,所以溫莎只是挑選第一個,哪裏是什麼「第一」的意思是不確定的。

確實,如果你切換在源代碼中的構造函數的順序您的代碼將開始工作,雖然這是一個黑客,依靠無證行爲,不這樣做。

讓我們回到我們開始的地方吧?

我說溫莎很困惑,因爲沒有它可以滿足最貪婪的構造函數。

快速而明確的解決將是一個假的參數添加到其中的一個構造函數,讓他們有不同數量的參數:

public class UserRepository : IUserRepository { 
    public UserRepository(IObjectContext objectContext, object fakeIgnoreMe) { 
     // Check that the supplied arguments are valid. 
     Validate.Arguments.IsNotNull(objectContext, "objectContext"); 
     // ignoring fake additional argument 
     // Initialize the local fields. 
     ObjectContext = objectContext; 
    } 

    public UserRepository(IObjectContextFactory factory) 
     : this(factory.CreateObjectContext()) { 
    } 

    // ----------------------------------------------- 
    // Insert methods and properties... 
    // ----------------------------------------------- 
} 

請將此問題報告給Castle users liststraight to issue tracker,這樣它會得到修復。

+0

曾爲勢如破竹!謝謝! – highvoltage 2009-11-17 12:39:27

+2

「溫莎試圖匹配最貪婪的構造函數(一個參數可以滿足最多的參數)」。我認爲「從構造函數列表中只包含可解析的參數,具有最多參數的構造函數被選中」是更正確的。 – Steven 2012-06-03 01:04:27

+0

@Steven現在怎麼樣? – 2012-06-05 14:09:40

0

至於溫莎3.2。x

如果將屬性Castle.Core.DoNotSelectAttribute應用於構造函數,則不會選擇該屬性,儘管存在任何其他條件。

public class UserRepository : IUserRepository 
{ 
    [DoNotSelect] // This constructor will be ignored by Windsor 
    public UserRepository(IObjectContext objectContext) 
    { 
     // ... 
    } 

    public UserRepository(IObjectContextFactory factory) 
     : this(factory.CreateObjectContext()) {} 
} 

參考:https://github.com/castleproject/Windsor/blob/86696989a7698c45b992eb6e7a67b765b48108b0/docs/how-constructor-is-selected.md