Dependency injection Ninject:构造函数参数
我正在与ASP.NETMVC4一起使用Ninject。我正在使用存储库,并希望进行构造函数注入,以将存储库传递给其中一个控制器 这是我的存储库界面:Dependency injection Ninject:构造函数参数,dependency-injection,asp.net-mvc-4,ninject,Dependency Injection,Asp.net Mvc 4,Ninject,我正在与ASP.NETMVC4一起使用Ninject。我正在使用存储库,并希望进行构造函数注入,以将存储库传递给其中一个控制器 这是我的存储库界面: public interface IRepository<T> where T : TableServiceEntity { void Add(T item); void Delete(T item); void Update(T item); IEnumerable<T> Find(para
public interface IRepository<T> where T : TableServiceEntity
{
void Add(T item);
void Delete(T item);
void Update(T item);
IEnumerable<T> Find(params Specification<T>[] specifications);
IEnumerable<T> RetrieveAll();
void SaveChanges();
}
请注意所需的tableName参数,因为我正在使用通用表存储库将数据持久化到Azure
最后,我有下面的控制器
public class CategoriesController : ApiController
{
static IRepository<Category> _repository;
public CategoriesController(IRepository<Category> repository)
{
if (repository == null)
{
throw new ArgumentNullException("repository");
}
_repository = repository;
}
创建DependencyResolver
是因为Ninject的DependencyResolver
实现了System.Web.Mvc.IDependencyResolver
,无法将其分配给WebApi应用程序的GlobalConfiguration.Configuration
因此,所有这些就绪后,Ninject部分实际上正在控制器中注入正确的类型,但Ninject无法在AzureTableRepository
的构造函数中注入tableName参数
在这种情况下,我如何才能做到这一点?我查阅了很多文章和ninject文档,以了解如何使用参数,但我似乎无法使其正常工作
任何帮助都将不胜感激。与此同时,我一直在与提供商周旋,尝试并实施这一技巧,似乎效果不错 我不知道这是一个好主意还是有点过火,但以下是我所做的: 我创建了一个通用提供程序类:
public abstract class NinjectProvider<T> : IProvider
{
public virtual Type Type { get; set; }
protected abstract T CreateInstance(IContext context);
public object Create(IContext context)
{
throw new NotImplementedException();
}
object IProvider.Create(IContext context)
{
throw new NotImplementedException();
}
Type IProvider.Type
{
get { throw new NotImplementedException(); }
}
}
公共抽象类提供程序:IProvider
{
公共虚拟类型类型{get;set;}
受保护的抽象T CreateInstance(IContext上下文);
创建公共对象(IContext上下文)
{
抛出新的NotImplementedException();
}
对象IProvider.Create(IContext上下文)
{
抛出新的NotImplementedException();
}
类型IProvider.Type
{
获取{抛出新的NotImplementedException();}
}
}
然后我在AzureTableRepositoryProvider中实现了这个。(T支持对多个实体类型具有相同的存储库。)
公共类AzureTableRepositoryProvider:提供程序
我会使用with constructorargument()
方法,比如
Bind<IRepository<Category>>().To<AzureTableRepository<Category>>()
.WithConstructorArgument("tableName", "categories");
Bind().To())
.带有构造函数参数(“表名”、“类别”);
存储库设计的其余部分可能是另一个问题。我觉得创建一张桌子或在一个房间里做任何繁重的工作似乎是一个很大的禁忌。我想我会删除这个创建。。。因为在构造函数中进行大量初始化确实不是一个好的实践。谢谢!
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
// Load the module that contains the binding
kernel.Load(new RepositoryNinjectModule());
// Set resolver needed to use Ninject with MVC4 Web API
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
}
public abstract class NinjectProvider<T> : IProvider
{
public virtual Type Type { get; set; }
protected abstract T CreateInstance(IContext context);
public object Create(IContext context)
{
throw new NotImplementedException();
}
object IProvider.Create(IContext context)
{
throw new NotImplementedException();
}
Type IProvider.Type
{
get { throw new NotImplementedException(); }
}
}
public class AzureTableRepositoryProvider<T> : Provider<AzureTableRepository<T>> where T : TableServiceEntity
{
protected override AzureTableRepository<T> CreateInstance(IContext context)
{
string tableName = "";
if (typeof(T).Name == typeof(Category).Name)
{
// TODO Get the table names from a resource
tableName = "categories";
}
// Here other types will be addedd as needed
AzureTableRepository<T> azureTableRepository = new AzureTableRepository<T>(tableName);
return azureTableRepository;
}
}
Bind<IRepository<Category>>().To<AzureTableRepository<Category>>()
.WithConstructorArgument("tableName", "categories");