ViewModelLocator 与 IOC 子容器?
当您使用 IOC 子容器时,如何实现 ViewModelLocator 模式?典型的定位器实现类似于:
public IViewModel ViewModel
{
get { return Services.ServiceLocator.GetInstance<IViewModel>(); }
}
其中 Services.ServiceLocator 是只读静态属性。但如果您使用子容器,这种情况就会崩溃。这是我使用子容器对 Services.ServiceLocator 的定义:
public static IServiceLocator ServiceLocator
{
get { return RootContext.ServiceLocator; }
}
显然这是不正确的:我注入的依赖项将来自根容器而不是子容器。 (子容器是由当前视图以外的其他内容创建和引导的。因此,我当前的视图可以从子容器自动连接。)
那么如何在多容器场景中获得正确的容器呢?标准答案是构造函数注入它,但这对于 ViewModelLocator 来说似乎不可能:它需要一个默认构造函数,以便可以从 XAML 构造它。
由于我正在开发 PRISM 复合应用程序(因此没有标记扩展),所以我也在寻找一个可以在 Silverlight 4 和 WPF 4.0 中工作的解决方案。我碰巧使用 Unity 作为 IOC 容器。哦,该解决方案应该在 Blend 中工作(也就是说,它不应该阻止创建绕过 IoC 容器的新设计时视图模型)。
How do you implement the ViewModelLocator pattern when you're using IOC child containers? A typical locator implementation is something like:
public IViewModel ViewModel
{
get { return Services.ServiceLocator.GetInstance<IViewModel>(); }
}
where Services.ServiceLocator is a read only static property. But this breaks down if you're using child containers. Here's my definition for Services.ServiceLocator using child containers:
public static IServiceLocator ServiceLocator
{
get { return RootContext.ServiceLocator; }
}
Clearly this is not correct: my injected dependencies will come from the root container instead of the child container. (The child container is created and boot strapped by something other than my current view. Thus my current view can auto wire from the child container.)
So how do you get the right container in a multiple container scenario? The standard answer is to constructor inject it, but that doesn't seem possible with the ViewModelLocator: it requires a default constructor so it can be constructed from XAML.
I'm also after a solution that works in both Silverlight 4 and WPF 4.0 since I'm working on a PRISM composite application (thus no markup extensions). I happen to be using Unity as the IOC container. Oh and the solution should work in Blend (that is, it should not prevent the creation of a new design time view model that bypasses the IoC container).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,子容器定义查找层次结构。但是,您的基本容器必须创建您的子容器 - 将其自身作为参数传递。
为了访问子容器,您可以拥有一个返回子容器的属性 - 可以是单例实例,也可以是瞬态(即新的)实例。但是,如果您想要可混合性,您应该注意,子容器需要位于您的资源中才能在设计时绑定到它。
在任何情况下,您都必须确保正确清理 ViewModel 的实例,以免产生内存泄漏。
编辑:
对于您的特殊情况这可能会有所帮助。尽管我没有时间观看视频,但 Laurent 告诉我,他正在演示一种动态加载视图模型的方法。我希望这对你有帮助!
Gennerally a child container defines a lookup hierarchy. However, your base container will have to create your child container - passing itself as a parameter.
In order to access the child container your can have a property that returns the child container - either a singleton instance or a transient (i.e. new) instance. If you want blendability you should, however, note that you the child container needs to be in your resources to bind to it at design time.
In any case you have to make sure that the instances of your ViewModels are properly cleaned up, so that no memory leaks are created.
Edit:
For your pecial case this might be helpful. Although I did not had time to watch the video Laurent told me that he was demonstrating a way of dynamicaly load the view model. I hope this does help you!