C# Ninject.MVC构造函数注入,其中注入的对象';s构造函数接受一个参数
您好,我在MVC3应用程序中使用Ninject.MVC Nuget包,我有一些构造函数注入的当前绑定设置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
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类型参数
我会的