我不得不重新编写一个大型 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 显示,但我有一些重要的问题......
- 我是否应该使用
ApplicationShellController
来初始化我的表单,目前不是使用 MVC“模式”? - 感觉我写了一个服务定位器,从我读到的内容来看,这很糟糕。我还应该如何使用 Ninject for IoC 来初始化我的应用程序?
- 关于我做对[如果有的话!]/错的任何其他建议?
非常感谢您的宝贵时间。
最佳答案
不,你不应该初始化你的 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 } }
这确实看起来像一个服务定位器,只需初始化您的 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()); } }
不要试图让它变得太复杂,一个好的开始很重要,但您始终可以在开发过程中随时随地应用更改。
我相信以下 GitHub 项目可能是一个很好的起点:Example of how you might use Ninject within a WinForms application.
如果你还有什么问题,请留下评论,我会尽快回答
关于c# - 使用 MVC 和 Ninject 作为 IoC 容器构建 WinForms 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35802180/