【问题标题】:Ninject passing reference in constructorNinject 在构造函数中传递引用
【发布时间】:2017-10-20 08:54:07
【问题描述】:

我是依赖注入的菜鸟,我按照教程重构了我的代码以使用 Ninject。这就是我所拥有的(简化)。 绑定.cs

 public class Bindings : NinjectModule
    {
        public override void Load()
        {
            Bind<IConnectionToModbusCreator>().To<ConnectionToModbusCreator>();
            Bind<IInputProcessor>().To<InputProcessor>();
}}

程序.cs ;

static class Program
    {
        [STAThread]
        static void Main()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            var InputProcessor = kernel.Get<IInputProcessor>();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1(InputProcessor));
}

这个启动一个form,用户通过点击一个按钮启动程序,这里是Form1:

    public partial class Form1 : Form
    {
        private readonly IInputProcessor _inputProcessor;

        public Form1(IInputProcessor inputProcessor)
        {            _inputProcessor = inputProcessor;
            InitializeComponent();
        }
        private void Test_Click_1(object sender, EventArgs e)
        {
  ISequenceController sequenceController = new SequenceController( _inputProcessor)
            sequenceController.StartSequence();
        }

我的问题是:

这是最好的方法吗?我对必须在构造函数中传递的所有引用感到担心,我尝试使用一个类 Container 来保存实例化对象的变量并将它们用作属性,但我在任何 Ninject 手册中都找不到 sich 方法。

【问题讨论】:

  • 您所做的称为构造函数注入,它是首选应用依赖注入的方式。你应该阅读a good book关于这个主题。
  • 谢谢,我阅读了很多教程和示例,我有一些代码要交付,甚至不需要注入,但我想利用这个机会制作 dome 好的现代代码。

标签: c# design-patterns dependency-injection constructor ninject


【解决方案1】:

您的程序遵循构造函数注入 DI 模式,这是一种很好的做法,但它有一些问题会引入模块之间的耦合。对new 的众多呼叫应该会提醒您。

  • Program 不应该知道 IInputProcessor。这是Form1 的依赖项
  • Form1 不应该知道 IInputProcessor。它是SequenceController 的依赖项
  • Form1不应该知道SequenceController,它应该只知道它的抽象,ISequenceController

这可以通过更好地使用构造函数注入来获得更少耦合的代码来解决:

public class Bindings : NinjectModule
    {
        public override void Load()
        {
            Bind<IConnectionToModbusCreator>().To<ConnectionToModbusCreator>();
            Bind<IInputProcessor>().To<InputProcessor>();
            Bind<ISequenceController>().To<SequenceController>();
            Bind<Form1>().ToSelf(); // in fact useless unless you add a scope, like .InSingletonScope()
        }
}

static class Program
    {
        [STAThread]
        static void Main()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form1= kernel.Get<Form1>();
            Application.Run(form1);
}

public partial class Form1 : Form
{
    private readonly ISequenceController _sequenceController;

    public Form1(ISequenceController sequenceController)
    {            
        _sequenceController = sequenceController;
        InitializeComponent();
    }

    private void Test_Click_1(object sender, EventArgs e)
    {
        _sequenceController.StartSequence();
    }

【讨论】:

  • 谢谢你看起来更整洁了!!
  • @Doraemon 很高兴阅读!不要忘记接受答案,以免您的问题看起来没有答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 2012-03-19
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多