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

标签 c# winforms model-view-controller ninject inversion-of-control

我不得不重新编写一个大型 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));
    }
}

我的 ApplicationShellView

public partial class ApplicationShellView : Form, IApplicationShellView
{
    public ApplicationShellView()
    {
        InitializeComponent();
    }

    public void InitializeView()
    {
        dockPanel.Theme = vS2012LightTheme;
    }
}

有接口(interface)

public interface IApplicationShellView
{
    void InitializeView();
}

这个 View 的 Controller 是

public class ApplicationShellController
{
    private IApplicationShellView view;

    public ApplicationShellController(IApplicationShellView view)
    {
        view.InitializeView();
    }
}

目前 Controller 是多余的,虽然这段代码有效并且我的 View 显示,但我有一些重要的问题......

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

非常感谢您的宝贵时间。

最佳答案

  1. 不,你不应该初始化你的 Controller ,这正是 IoC 和 Ninject 的目的。当你初始化你的 View /表单时,Ninject 应该让 View 获取它依赖的 Controller ,这将自动获取它依赖的 Controller 等等。
    当然,这不会像您现在设置的那样起作用。对于初学者,您的 View 需要知道它所依赖的 Controller 。

    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. 这确实看起来像一个服务定位器,只需初始化您的 View 就足够了。

    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 项目可能是一个很好的起点:Example of how you might use Ninject within a WinForms application.

如果你还有什么问题,请留下评论,我会尽快回答

关于c# - 使用 MVC 和 Ninject 作为 IoC 容器构建 WinForms 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35802180/

相关文章:

c# - WPF TreeView 双击后恢复焦点

c# - 是否可以通过 Azure 中运行的 Web API 对 Azure 外部的应用程序进行 HTTP 调用?

c# - 如何从一个值中选择两个值

c# - 在 Unity C# 中使用 2D 数组解析 JSON

winforms - 使用 Treeview 和拆分控件在 Winforms 中实现拖放

c# - 拖放至 Windows 窗体问题

ios - 一个类应该在内部处理它自己的数据吗?

java - Spring MVC - DispatcherServlet 通过注释

model-view-controller - 将 RESTful API 端点概念化为 MVC 设计模式中的 View

C# winform 按钮点击后边框内