我目前正在开发一个项目,我们将旧的DataSet,存储过程WinForm应用程序转换为使用实体框架,以便新网站可以访问相同的对象模型和存储库。
无论如何,我正在尝试在表单中实现依赖注入,以便我们可以使用模拟的存储库进行单元测试。我使用Ninject的原因很简单,我之前在MVC网站中使用过Ninject,但是在WinForm应用程序中尝试实现这一点,至少可以证明是有问题的,因为在WinForms中缺乏有关DI的信息而更加困难。网络。
到目前为止,我已经创建了Ninject Factory和存储库,但是我没有太多运气将存储库注入表单。
因此,任何人都可以帮助我或提出任何建议吗?
下面我的部分代码可能有所帮助:
Ninject Factory:
public class NinjectFactory : NinjectModule
{
private IKernel _ninjectKernel;
public NinjectFactory()
{
_ninjectKernel = new StandardKernel();
}
public override void Load()
{
_ninjectKernel.Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>));
_ninjectKernel.Bind(typeof(IProductionRepository)).To(typeof(ProductionRepository));
}
}
包含存储库的表单:
Public Class TaskForm
Inherits BaseBusinessDialogForm
Private _repository As TaskRepository
Private _task As Production.Task = Nothing
Public Sub New(ByVal task As Production.Task)
InitializeComponent()
_repository = New TaskRepository(ConnectString)
If task.TaskID = 0 Then
_task = task
Else
_task = _repository.GetByID(task.TaskID)
End If
MyBase.BusinessObject = _task
Me.TaskBindingSource.DataSource = MyBase.BusinessObject
End Sub
启动包含上述表单的MDI表单的类:
Dim kernel As IKernel = New StandardKernel(New NinjectFactory())
''Dim kernel As IKernel = New StandardKernel(New NinjectFactoryTest())
mfrmMDI = kernel.Get(Of Forms.MDI)()
Application.DoEvents()
mfrmMDI.ShowDialog()
我理解我的问题有点模糊,但我不确定问题出在哪里或我需要完成什么。
非常感谢
答案 0 :(得分:35)
您可以将合成根创建为解决方案的一个入口点。您将INjectModule作为参数传递,以便您可以配置它以不同方式进行测试。 Composition Root的一个好处是,并非所有程序集都依赖于NInject,并且您将只有一个单点来更改分辨率逻辑。这可能是一个很酷的模式,你可能会在未来更改IoC容器或引入一些动态拦截。
public class CompositionRoot
{
private static IKernel _ninjectKernel;
public static void Wire(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(IRepository<>)).To(typeof(GenericRepository<>));
}
}
在主要方法中,您将ApplicationModule
作为参数传递并解析Form1
并启动它。
[STAThread]
static void Main()
{
CompositionRoot.Wire(new ApplicationModule());
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(CompositionRoot.Resolve<Form1>());
}
在Form1
构造函数中,您传递了具有特定封闭通用参数的必需存储库
public partial class Form1 : Form
{
private IRepository<Process> _processRepository;
public Form1(IRepository<Process> productionRepository)
{
this._processRepository = productionRepository;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(_processRepository.ToString());
}
}
您的存储库可能非常复杂,但我不会向它们添加任何功能,而不是ToString()
方法,以便我们可以看到依赖项是否已正确解析。请注意,存储库中没有任何属性。
public interface IRepository<T>
{
}
public class GenericRepository<T> : IRepository<T>
{
public override string ToString()
{
return "MyRepository with type : "+typeof(T).Name;
}
}
现在,当您运行应用程序时,您将看到所有已连线并且消息框显示封闭类型为Process