问题描述
我需要一个应用程序架构的建议。
我建设有通知区域图标支持.NET 4的WPF桌面应用程序。
应用有几个窗口,这显示在启动时,再关闭掉,只通知区域图标仍然存在。
的通知区域图标纯粹是WPF控件,我从这个得了一> $ C $的CProject例子。
由于我的应用程序仍应当所有的窗口都关闭了,我即使设定运行
ShutdownMode =OnExplicitShutdown
在App.xaml中。
我将介绍我的一种体系结构和启动机制的想法,你告诉我,我错了,如果可能指正。
在App.xaml.cs我创建一个Ninject StandardKernel
,姑且称之为 appKernel
并加载Ninject模块分成它。起初只有一个接口是由Ninject解决 - 一个 heartbeatManager
实例。一个HeartbeatManager是一类我刨使用的:
一)托管我NotifyIcon的实例作为场变量,以便它reamins可见只要类的实例是在存储器
二)关机事件的执行情况,我会在app.xaml.cs并明确关闭的应用程序认购,当心跳类要求它。
在这一点上 heartbeatManager
实例被创建只是留在记忆挂起。
在App.xaml中我设置了的StartupUri =MainWindow.xaml
以创建主窗口并显示。继主窗口尝试解析它在App.xaml中定义的静态ViewModelLocator实例数据上下文中的MVVM光ViewModelLocator模式:
< Application.Resources>
<的ViewModels:ViewModelLocator X:键=定位器D:IsDataSource =真/>
< /Application.Resources>
ViewModelLocator实例被创建,并在构造函数中进行初始化另一个StandardKernel(是否有任何其他类型的内核我在这一点上喊使用?的),将被用于解决视图模型绑定。提供了一个主窗口的视图模型以满足窗户的要求,整个应用程序继续运行。
有一个很重要的启示,就是hearbeatManger实例绑定在一个singletone范围的接口定义,因此需要它作为一个构造函数的参数,视图模型能够解决,并获得已创建的实例。将这种依赖性解析工作,如果视图模型和heartbeatManager在一个不同的内核加载?如果没有,我怎么能解决这个问题?
时的上述情景规划有什么好的架构,明智的,它是在code实现的,或有我犯了一个错误,当我通过架构?
思维If it is registered with your kernel, it isn't any magic that causes it to hang in memory - it will stick around as long as the kernel/container does. That container should probably be a member of your App class, since your app class sticks around as long as the (compiler generated) Main
method does, and you should dispose it on app shutdown anyhow.
I'm not sure this will mix well with NInject. It is a Dependency Injection container, not a Service Locator container (even though it uses one under the hood). The main purpose of NInject (and similar frameworks) is to avoid requiring you to use the Service Locator pattern, and instead to inject all your dependencies.
Unless your scenario is quite complicated (which it really isn't for this app), then I suggest sticking to a single NInject kernel.
Suggested Solution
The view model locator class itself doesn't do much for you other than let you split up your initialization logic, and do selective initialization depending on whether you're in design mode or runtime mode. You could achieve the same with NInject modules (which the view model locator article you linked in comments already uses).
I suggest that instead of using a view model locator, you specify all your components in your module class, and do the IsInDesignMode
logic in the Load
method.
This might be a bit tricky with MVVM though, since the view model needs to bind to an object
property you didn't create, and can't annotate.
There are a few ways to solve this directly in NInject, instead of resorting to a service locator:
- Use Dependency Injection on your view, making it require a view model.
If this doesn't work using constructor injection (as you mentioned in your comments), use property injection instead, with a custom property that forwards its setter toDataContext
. - Use NInject factory methods (
ToMethod
) to create your view, and bind the view model to the view in each factory method.
E.g.Bind<MainView>().ToMethod(context => new MainView() { DataContext = new MainViewModel() });
If you can, I'd go for the second method. This way your view doesn't have to handle data binding, and doesn't have to have any code behind. It is also simple to understand, would let you avoid having to register both views and view models in the kernel, and would let you avoid making any sort of well known interface for your view model.
这篇关于MVVM光,Ninject在大多通知区域的应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!