我有一个场景,我想在容器中注册一个组件的单个实例,但遗憾的是它无法在应用程序启动时创建。 该组件只能被实例化传递一些对象,其仅可位在后面应用程序生命周期(它们不是其他的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) { ... }
}
我不满意的解决方案:
public class ShellView : Window {
internal DockControl theDockControl;
public ShellView () {
InitializeComponents();
var dockManager = new AcmeDockManagerAdapter(theDockControl);
//registration in the container
}
}
答案 0 :(得分:1)
您可以注册“懒惰包装”。这样的包装器实现了相同的接口,可以立即实例化,但会在内部推迟创建工作的实际组件。看看ploeh的LazyOrderShipper或LazyOrderShipper2。
示例编辑:如果我理解正确,您只是尝试将视图连接到视图模型,MVVM风格。我更喜欢让容器处理viewmodel构造,而是自己做视图构造和viewmodel布线。我的启动代码看起来像这样:
var mainViewModel = container.Get<MainViewModel>();
var mainView = new MainView(mainViewModel);
Application.Run(mainView);
在MainView
构造函数中,我会处理需要自己的viewmodel的子控件:
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中允许可插入视图时,事情变得更有趣,但这是另一个故事。)
答案 1 :(得分:1)
我理解问题的解决方案相对简单 - 从外部提供theDockControl
。我知道这会搞乱自动生成的WinForms / WPF /无论你使用什么废话,但我担心这里没有漂亮的解决方案。