使用 MVC 和 Ninject 作为 IoC 容器构建 WinForms 应用程序
本文关键字:构建 WinForms 应用程序 IoC MVC Ninject 作为 使用 | 更新日期: 2023-09-27 18:37:21
我不得不重写一个大型的WinForms应用程序,我想使用MVC来增加测试能力等。我还想采用 Ninject 作为我的 IoC 容器,因为它是轻量级的、快速的,并且会提高我的应用程序的可扩展性。
我已经做了大量的阅读,并且我设法开始了这个新应用程序的构建。但是,我不确定我在使用 Ninject 时是否有正确的想法。代码...
从程序开始.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));
}
}
我的ApplicationShellView
是
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
来初始化我的表单,目前这不是使用 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的示例。
如果您还有其他问题,请发表评论,我会尽快回答