Ninject 在构造函数中传递引用
Ninject passing reference in constructor
我是依赖注入的菜鸟,我按照教程重构了我的代码以使用 Ninject。这就是我所拥有的(简化)。
Bindings.cs
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IConnectionToModbusCreator>().To<ConnectionToModbusCreator>();
Bind<IInputProcessor>().To<InputProcessor>();
}}
Program.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));
}
这里启动一个窗体,用户通过点击一个按钮启动程序,这里是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();
}
我的问题是:
这是最好的方法吗?我担心我必须在构造函数中传递的所有引用,我尝试使用 class 容器,它保持实例化对象的变量并将它们用作属性,但我在任何 [=27= 中找不到 sich 方法] 手册。
您的程序遵循构造函数注入 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();
}
我是依赖注入的菜鸟,我按照教程重构了我的代码以使用 Ninject。这就是我所拥有的(简化)。 Bindings.cs
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IConnectionToModbusCreator>().To<ConnectionToModbusCreator>();
Bind<IInputProcessor>().To<InputProcessor>();
}}
Program.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));
}
这里启动一个窗体,用户通过点击一个按钮启动程序,这里是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();
}
我的问题是:
这是最好的方法吗?我担心我必须在构造函数中传递的所有引用,我尝试使用 class 容器,它保持实例化对象的变量并将它们用作属性,但我在任何 [=27= 中找不到 sich 方法] 手册。
您的程序遵循构造函数注入 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();
}