使用 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();
    }
}

目前控制器是冗余的,虽然这段代码可以工作并且我的视图显示,但我有一些重要的问题......

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

非常感谢您的时间。

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

  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<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
        }
    }
    
  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<IApplicationShellController>().To<ApplicationShellController>();
            //We can also load other modules this project depends on.
            Kernel.Load(new NinjectModule());
        }
    }
    
  3. 不要试图让它太复杂,一个好的开始很重要,但在开发过程中,您始终可以在需要的时间和地点应用更改。

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

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