C# Ninject.MVC构造函数注入,其中注入的对象';s构造函数接受一个参数

C# Ninject.MVC构造函数注入,其中注入的对象';s构造函数接受一个参数,c#,asp.net-mvc,asp.net-mvc-3,dependency-injection,ninject,C#,Asp.net Mvc,Asp.net Mvc 3,Dependency Injection,Ninject,您好,我在MVC3应用程序中使用Ninject.MVC Nuget包,我有一些构造函数注入的当前绑定设置 private static void RegisterServices(IKernel kernel) { kernel.Bind<IUnitOfWork>().To<ERSUnitOfWork>(); kernel.Bind<IRepository<Recipe>>().To<Gener

您好,我在MVC3应用程序中使用Ninject.MVC Nuget包,我有一些构造函数注入的当前绑定设置

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IUnitOfWork>().To<ERSUnitOfWork>();
        kernel.Bind<IRepository<Recipe>>().To<GenericRepository<Recipe>>();
    }
私有静态无效注册服务(IKernel内核)
{
kernel.Bind().To();
kernel.Bind().To();
}
我的控制器示例如下:

public class RecipesController : Controller
{
    private readonly IUnitOfWork unitOfWork;
    private readonly ERSDbContext context;
    private readonly IRepository<Recipe> recipeRepository;

    public RecipesController(IUnitOfWork unitOfWork, IRepository<Recipe> recipeRepository)
    {
        this.context = new ERSDbContext();
        this.unitOfWork = unitOfWork;
        this.recipeRepository = recipeRepository;
    }
}
公共类控制器:控制器
{
私有只读IUnitOfWork;
私有只读ERSDbContext上下文;
私人只读易读易读;
公共配方控制器(IUnitOfWork、IRepository RecipereRepository)
{
this.context=新的ERSDbContext();
this.unitOfWork=unitOfWork;
this.recipeRepository=recipeRepository;
}
}
我想从控制器中删除私有DBContext属性,并将新的ERSDbContext()传递给ERSUnitOfWork和GenericRepository的构造函数,作为Ninject正在执行的构造函数注入的一部分,但最好将ERSDbContext类的初始化保留在控制器中

如果您能提供帮助,我们将不胜感激。谢谢


我希望它不需要我的NinjectWebCommon类创建DbContext,我希望它在控制器中初始化。

这是如何抽象依赖项的问题

因为您想控制创建实例的时间,所以应该有一个工厂来创建特定于类型的
DbContext
实例,如下所示:

public interface IDbContextFactory
{
     T CreateDbContext<T>() where T : DbContext;
}
然后定义如下实现:

public class DbContextFactory : IDbContextFactory
{

    #region Implementation of IDbContextFactory

    public T CreateDbContext<T>() where T : DbContext, new()
    {
        // Create a new instance of T and return.
        return new T();
    }

    #endregion
}
公共类DbContextFactory:IDbContextFactory
{
#IDbContextFactory的区域实现
public T CreateDbContext(),其中T:DbContext,new()
{
//创建T的新实例并返回。
返回新的T();
}
#端区
}
如果需要调用不同的构造函数,则需要删除,并且必须使用反射调用(或者,可以创建lambda表达式并基于
T
的类型对其进行缓存)来创建类型化的
DbContext


从那里,您可以将
IDbContextFactory
契约与实现相关联,并将
IDbContextFactory
实现注入到类中,就像其他接口一样。

这是如何抽象依赖项的问题

因为您想控制创建实例的时间,所以应该有一个工厂来创建特定于类型的
DbContext
实例,如下所示:

public interface IDbContextFactory
{
     T CreateDbContext<T>() where T : DbContext;
}
然后定义如下实现:

public class DbContextFactory : IDbContextFactory
{

    #region Implementation of IDbContextFactory

    public T CreateDbContext<T>() where T : DbContext, new()
    {
        // Create a new instance of T and return.
        return new T();
    }

    #endregion
}
公共类DbContextFactory:IDbContextFactory
{
#IDbContextFactory的区域实现
public T CreateDbContext(),其中T:DbContext,new()
{
//创建T的新实例并返回。
返回新的T();
}
#端区
}
如果需要调用不同的构造函数,则需要删除,并且必须使用反射调用(或者,可以创建lambda表达式并基于
T
的类型对其进行缓存)来创建类型化的
DbContext


从那里,您可以将
IDbContextFactory
契约与实现相关联,并将
IDbContextFactory
实现注入到类中,就像注入任何其他接口一样。

这是依赖项注入的好处之一,它将自动解析所有构造函数参数及其依赖的构造函数参数。它为您完成了所有这些,只需要定义对象的映射

因此,在您的情况下,您只需执行以下操作:

kerel.Bind<ERSDbContext>().ToSelf();
kerel.Bind().ToSelf();
然后,您只需将ERSDbContext添加到UoW和回购协议中,就可以了

如果您想进行单元测试,那么您将需要以某种方式抽象您的上下文,如casperOne所述或如我所述(您将DbContext派生自通用接口),然后改为执行以下操作:

kernel.Bind<IDbContext>().To<ERSDbContext>();
kernel.Bind().To();
使用DI的好处之一是它控制对象的生存期。如果将DbContext的构造推迟到DI容器外部,则必须手动管理其生存期,而不是允许DI容器基于生存期策略(例如在请求结束时自动销毁)来管理它


我认为延迟创建上下文没有明显的好处。我认为您正在进行过早的优化。

这是依赖项注入的好处之一,它将自动解析所有构造函数参数及其依赖构造函数参数。它为您完成了所有这些,只需要定义对象的映射

因此,在您的情况下,您只需执行以下操作:

kerel.Bind<ERSDbContext>().ToSelf();
kerel.Bind().ToSelf();
然后,您只需将ERSDbContext添加到UoW和回购协议中,就可以了

如果您想进行单元测试,那么您将需要以某种方式抽象您的上下文,如casperOne所述或如我所述(您将DbContext派生自通用接口),然后改为执行以下操作:

kernel.Bind<IDbContext>().To<ERSDbContext>();
kernel.Bind().To();
使用DI的好处之一是它控制对象的生存期。如果将DbContext的构造推迟到DI容器外部,则必须手动管理其生存期,而不是允许DI容器基于生存期策略(例如在请求结束时自动销毁)来管理它


我认为延迟创建上下文没有明显的好处。我认为您正在进行过早的优化。

由于我的并发性问题,我暂时取消了对factory的使用,我使用这种方法是因为我时间不够

kernel.Bind<ERSDbContext>().ToSelf().InRequestScope();
kernel.Bind().ToSelf().InRequestScope();
然后在my UoW和GenericRepository中,构造函数需要一个ERSDbContext类型参数

我会的