1

我有一個場景,我想在容器中註冊一個組件的單個實例,但不幸的是它不能在應用程序啓動時創建。 該組件只能被實例化,傳遞一些對象,這些對象僅在應用程序生命週期中稍後提供(但它們不是其他IoC註冊服務,但是)[請參見下面的註釋]在初始配置後在IoC容器中註冊

  • 處於IoC容器註冊部件後的初始配置(在應用程序啓動時運行)一種不好的做法?
  • 如何在不直接引用容器的情況下完成它?我應該抽象一個註冊服務嗎?
  • 有更好的方法來支持這種情況?

注:關於實際情況
我想放在容器與UI控件的特定實例初始化成分(這基本上是一個適配器),所以我不得不手動創建組件實例並將其註冊到容器中。
我會在應用程序啓動時做到這一點,但不幸的是我沒有可用的UI控件實例(我也不能自己創建它)。
即使在以後,我也無法從其他組件的表面到達UI控件實例,而不知道它們的具體類。
因此,我認爲我可以將適配器註冊的責任放入擁有UI控件的類中。

我的初步方案:

public interface IDockManager { ... } 
public class AcmeDockManagerAdapter : IDockManager { 
    public AcmeDockManager(DockControl control) { ... } 
    ... 
} 

public class ShellViewModel { ... } 
public class ShellView : Window { 
    internal DockControl theDockControl; 
} 

public class AnotherViewModel { 
    AnotherViewModel(IDockManager dockManager) { ... } 
} 

我unconfortable與解決方案:

public class ShellView : Window { 
    internal DockControl theDockControl; 
    public ShellView() { 
     InitializeComponents(); 
     var dockManager = new AcmeDockManagerAdapter(theDockControl); 
     //registration in the container 
    } 
} 

回答

1

你可以註冊一個 「懶包裝」 來代替。這樣的包裝器實現相同的接口並可以立即實例化,但會在內部推遲創建實際工作的實際組件。看看ploeh的例子LazyOrderShipperLazyOrderShipper2

編輯:如果我理解正確,你只是試圖將你的視圖連接到你的視圖模型,MVVM風格。我更喜歡讓容器處理viewmodel構造,但是要自己做視圖構造和視圖模型佈線。我的啓動代碼看起來竟被這樣的:

var mainViewModel = container.Get<MainViewModel>(); 
var mainView = new MainView(mainViewModel); 
Application.Run(mainView); 

而且MainView構造函數中我會照顧好它需要自己的視圖模型子控件:

public MainView(MainViewModel viewModel) 
    { 
     // link "subviews" to "subviewmodels" 
     this.SomeChildControl.ViewModel = viewModel.SomeChildViewModel; 

     // normal MVVM property wiring 
     viewModel.TitleChanged += delegate { this.Text = viewModel.Title; }; 
     ... 
    } 

如果嚴格遵循MVVM方法,那麼你不應該註冊任何視圖與容器。任何「需要與觀點對話」都需要與底層視圖模型進行對話。 (當你希望在標籤界面或停靠窗口GUI中允許插入視圖時,事情會變得更有趣,但那是另一回事。)

+0

這是一個非常優雅的解決方案。然而,我的問題與組件實例的成本無關,而是與某些構造器參數的可用性有關。推遲實際的實例化要求至少懶惰的包裝器知道如何檢索所需的參數,當它最終到達創建實例時。 我應該更詳細地解釋我的情況,也許(我將要這樣做)。謝謝你的幫助。 – 2010-12-18 09:29:01

+0

對不起,但問題與視圖和虛擬機之間的連線沒有關係(這已經到位)。我只是添加了實際的類,希望能夠澄清上下文。 我的意圖是抽象對接部分並將其接口從ShellVM中分離出來,確切目的是允許動態添加。 我希望將對接服務放在容器中以簡化依賴注入,但我可以肯定從ShellVM(它已經在容器中註冊爲單例)訪問它。 – 2010-12-18 19:27:19

1

解決方案我明白這個問題,相對簡單 - 從外面提供theDockControl。我知道這是與自動生成的WinForms/WPF /無論你使用廢話混亂,但我恐怕沒有漂亮的解決方案在這裏。

+0

我想你有點不安。從設計的角度來看,從外部向適配器和窗口提供相同的控件實例是最好的選擇 - 而且非常簡單!由於其他原因可能會很尷尬,但這是另一個問題。 我想延期登記是無可爭議的,雖然... 非常感謝您的幫助。 – 2010-12-19 10:03:58

+0

不用擔心。下次你會得到徽章:) – 2010-12-19 23:59:03