使用Ninject和Entity框架的WinForms中的依赖注入

我正在开发一个项目,我们将旧的DataSet,存储过程WinForm应用程序转换为使用实体框架,以便新的网站可以访问相同的对象模型和存储库。

无论如何,我试图在表单中实施依赖注入,以便我们可以使用模拟的存储库进行单元测试。我正在使用Ninject,因为我在MVC网站之前使用它的简单原因,但是试图在WinForm应用程序中实现这一点,证明是至关重要的,因为在WinForms中缺少关于DI的信息网络。

到目前为止,我已经创建了Ninject Factory和存储库,但是我没有多少运气将存储库注入到表单中。

所以任何人都可以帮我或提出任何建议吗?

下面我有部分代码可能有帮助:

NINject工厂:

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()

我明白我的问题有点模糊,但我不知道问题在哪里或我需要完成的地方。

非常感谢

您创建组合根作为决议的一个入口点。您将INjectModule作为参数传递,以便您可以将其配置为不同的测试。组合根的好处之一在于,并不是所有的程序集都将依赖于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<>));
    }
}

在main方法中,将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

相关文章

什么是设计模式一套被反复使用、多数人知晓的、经过分类编目...
单一职责原则定义(Single Responsibility Principle,SRP)...
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强...
适配器模式将一个类的接口转换成客户期望的另一个接口,使得...
策略模式定义了一系列算法族,并封装在类中,它们之间可以互...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,...