我必须重新编写一个大型 WinForms 应用程序,并且我想使用 MVC 来增强测试能力等。我还想采用 Ninject 作为我的 IoC 容器,因为它轻量、快速,并且会增加我的应用程序未来的可扩展性。
我进行了大量的阅读,并成功地开始了解这个新应用程序的架构。但是,我不确定使用 Ninject 时我的想法是否正确。代码...
从 Program.cs 和相关类开始...
static class Program
{
[STAThread]
static void Main()
{
FileLogHandler fileLogHandler = new FileLogHandler(Utils.GetLogFilePath());
Log.LogHandler = fileLogHandler;
Log.Trace("Program.Main(): Logging initialized");
CompositionRoot.Initialize(new ApplicationModule());
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(CompositionRoot.Resolve<ApplicationShellView>());
}
}
public class CompositionRoot
{
private static IKernel _ninjectKernel;
public static void Initialize(INinjectModule module)
{
_ninjectKernel = new StandardKernel(module);
}
public static T Resolve<T>()
{
return _ninjectKernel.Get<T>();
}
}
public class ApplicationModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IApplicationShellView)).To(typeof(ApplicationShellView));
}
}
An my ApplicationShellView
is
public partial class ApplicationShellView : Form, IApplicationShellView
{
public ApplicationShellView()
{
InitializeComponent();
}
public void InitializeView()
{
dockPanel.Theme = vS2012LightTheme;
}
}
带接口
public interface IApplicationShellView
{
void InitializeView();
}
该视图的控制器是
public class ApplicationShellController
{
private IApplicationShellView view;
public ApplicationShellController(IApplicationShellView view)
{
view.InitializeView();
}
}
目前控制器是多余的,尽管此代码有效并且我的视图显示,但我有一些重要的问题......
- 我应该使用
ApplicationShellController
初始化我的表单,目前这是not使用MVC“模式”?
- 感觉就像我写了一个服务定位器,从我读到的内容来看,这很糟糕。我还应该如何使用 Ninject for IoC 来初始化我的应用程序?
- 关于我所做的正确[如果有的话!]/错误还有其他建议吗?
非常感谢你花时间陪伴。
-
不,你不应该初始化你的控制器,这正是 IoC 和 Ninject 的用途。当你初始化视图/表单时,Ninject 应该让视图获取它所依赖的控制器,这将自动获取它所依赖的控制器等等。
当然,这不会像您现在设置的那样起作用。对于初学者来说,您的视图需要知道它所依赖的控制器。
public partial class ApplicationShellView : Form, IApplicationShellView
{
private IApplicationShellController _controller;
public ApplicationShellView()
{
InitializeComponent();
init();
//InitializeView()
}
private void init() {
_controller = NinjectProgram.Kernel.Get<IApplicationShellController>();
//Because your view knows the controller you can always pass himself as parameter or even use setter to inject
//For example: _controller.SetView1(this);
}
public void InitializeView()
{
dockPanel.Theme = vS2012LightTheme;
}
}
public class ApplicationShellController : IApplicationShellController
{
//Implementes functionality for the MainForm.
public ApplicationShellController()
{
//Also possible to add other controllers with DI
}
}
-
这确实看起来像一个服务定位器,只需初始化您的视图就足够了。
public class NinjectProgram
{
//Gets the inject kernal for the program.
public static IKernel Kernel { get; protected set; }
}
public class Program : NinjectProgram
{
[STAThread]
private static void Main()
{
Kernel = new StandardKernel();
Kernel.Load(new ApplicationModule());
Application.Run(new ApplicationShellView());
}
}
public class ApplicationModule : NinjectModule
{
public override void Load()
{
//Here is where we define what implementations map to what interfaces.
Bind<IApplicationShellController>().To<ApplicationShellController>();
//We can also load other modules this project depends on.
Kernel.Load(new NinjectModule());
}
}
不要试图让它变得太复杂,一个好的开始很重要,但您可以在开发过程中随时随地根据需要应用更改。
我相信以下 GitHub 项目可能是一个很好的起点:如何在 WinForms 应用程序中使用 Ninject 的示例。 https://gist.github.com/dkellycollins/9c3fecaedd830094d7f2
如果您还有其他问题,请发表评论,我会尽快回答
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)