Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Ninject和实体框架在WinForms中进行依赖项注入_Winforms_Entity Framework_Dependency Injection_Ninject - Fatal编程技术网

使用Ninject和实体框架在WinForms中进行依赖项注入

使用Ninject和实体框架在WinForms中进行依赖项注入,winforms,entity-framework,dependency-injection,ninject,Winforms,Entity Framework,Dependency Injection,Ninject,我目前正在从事一个项目,我们正在将旧的数据集、存储过程WinForm应用程序转换为使用实体框架,以便新网站可以访问相同的对象模型和存储库 无论如何,我正在尝试将依赖项注入到表单中,以便我们可以使用模拟存储库进行单元测试。我之所以使用Ninject,原因很简单,因为我以前在MVC网站上使用过它,但是在WinForm应用程序中尝试实现这一点,至少可以说是有问题的,因为web上WinForms中缺少关于DI的信息,这就更加阻碍了我 到目前为止,我已经创建了Ninject工厂和存储库,但是我没有太多的运

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

无论如何,我正在尝试将依赖项注入到表单中,以便我们可以使用模拟存储库进行单元测试。我之所以使用Ninject,原因很简单,因为我以前在MVC网站上使用过它,但是在WinForm应用程序中尝试实现这一点,至少可以说是有问题的,因为web上WinForms中缺少关于DI的信息,这就更加阻碍了我

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

因此,谁能帮助我或提出任何建议

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

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));
    }
}
类启动保存上述表单的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()
我知道我的问题有点模糊,但我不确定问题出在哪里,或者我需要完成什么


非常感谢

您创建了composition root作为解决方案的一个入口点。您可以将INjectModule作为参数传递,以便以不同的方式对其进行配置。CompositionRoot的一个好处是,并不是所有程序集都依赖于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>();
    }
}
Form1
constructor中,您通过特定的封闭通用参数传递所需的存储库

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());
    }
}
现在,当您运行应用程序时,您将看到,所有这些都已连接,消息框显示一个封闭的类型,即
Process


如果你混合了VB和C语言,是否可以只在C语言上给出答案?很抱歉混合了多种语言,这是直接从项目代码中获得的。旧的东西在VB中,新的东西在C#中,至少可以说很烦人!非常感谢,我已经成功地实现了您的示例的一个版本。我认为您没有理解合成根的意图。您的“组合根”实际上是一个服务定位器,它通常被认为是一个反模式。真正的组合根是正在运行的应用程序对象图中的“顶级”对象,并且应该是您明确要求内核提供的唯一对象(不包括工厂)。所有其他问题都应该在构造根时通过注入解决,或者通过工厂实例化解决。IKernel中的
public T Get()
是否使其成为服务定位器?如果它是静态的,并不意味着它是服务定位器。我不想使用
Form1
作为合成根目录,因为它有自己的逻辑,在测试中您不想触及它。此外,在测试中,您还应该创建另一个CompositionRoot?我想我明白您的意思了。MarkSeeman在他的网站上提供了类似的服务定位器示例。但有一些关键的区别-SL使用字典,这是关键的,在构造函数中也可以调用SL.Resolve,而我只在一个地方调用根,而不在其他地方调用根。如果有任何误解留下-请note@IlyaIvanov,在这个简单的场景中看起来不错。我想知道,如果我的“主”表单必须创建子表单(也使用DI),您认为最佳实践是什么。如何避免在那里调用CompositionRoot.Resolve方法(该方法将被视为“邪恶服务定位器”)?谢谢你的更新。
public class ApplicationModule : NinjectModule
{
    public override void Load()
    {
        Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>));
    }
}
[STAThread]
static void Main()
{
    CompositionRoot.Wire(new ApplicationModule());

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    Application.Run(CompositionRoot.Resolve<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());
    }
}
public interface IRepository<T>
{
}

public class GenericRepository<T> : IRepository<T>
{
    public override string ToString()
    {
        return "MyRepository with type : "+typeof(T).Name;
    }
}