使用MVC和Ninject作为IoC容器构建WinForms应用程序

我不得不重新编写一个大型的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()); } } public class CompositionRoot { private static IKernel _ninjectKernel; public static void Initialize(INinjectModule module) { _ninjectKernel = new StandardKernel(module); } public static T Resolve() { return _ninjectKernel.Get(); } } 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(); } } 

目前控制器是多余的,虽然这个代码有效并且我的视图显示,但我有一些重要的问题……

  1. 我应该使用ApplicationShellController来初始化我的表单,目前这不是使用MVC“模式”吗?
  2. 感觉就像我写了一个服务定位器,从我读过的,这很糟糕。 我应该如何使用Ninject for IoC来初始化我的应用程序?
  3. 关于我正在做什么的任何其他建议[如果有的话] /错误?

非常感谢你花时间陪伴。

  1. 不,你不应该初始化你的控制器,这正是IoC和Ninject的用途。 初始化视图/表单时,Ninject应该使视图获取它所依赖的控制器,这将自动获取它所依赖的控制器,依此类推。
    当然,这不会像你现在设置的那样起作用。 对于初学者,您的视图需要知道它所依赖的控制器。

     public partial class ApplicationShellView : Form, IApplicationShellView { private IApplicationShellController _controller; public ApplicationShellView() { InitializeComponent(); init(); //InitializeView() } private void init() { _controller = NinjectProgram.Kernel.Get(); //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 } } 
  2. 这确实看起来像服务定位器,只需初始化您的视图就足够了。

     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().To(); //We can also load other modules this project depends on. Kernel.Load(new NinjectModule()); } } 
  3. 不要试图让它变得太复杂,一个良好的开端很重要,但你总是可以在开发过程中随时随地应用更改。

我相信以下GitHub项目可能是一个很好的起点: 在WinForms应用程序中如何使用Ninject的示例。

如果您还有其他问题,请发表评论,我会尽快回复