C# 如何使用Ninject将通用接口注入MVC控制器
我有以下情况: 接口:C# 如何使用Ninject将通用接口注入MVC控制器,c#,asp.net-mvc,dependency-injection,ninject,C#,Asp.net Mvc,Dependency Injection,Ninject,我有以下情况: 接口: public interface ITest<T> where T:class { void Delete(T item); } 抽象实现: public abstract class Test<T>:ITest<T> where T:class { private readonly ApplicationDbContext _context; protected Test(A
public interface ITest<T> where T:class
{
void Delete(T item);
}
抽象实现:
public abstract class Test<T>:ITest<T> where T:class
{
private readonly ApplicationDbContext _context;
protected Test(ApplicationDbContext context){
_context=context;
}
public void Delete(T item) { }
}
最后一节课:
public class RepoTest:Test<FirstEntity>
{
public void DoSomething() { }
}
我有一个MVC控制器,看起来像这样:
public abstract class MyController<T>:Controller where T:class
{
private readonly ITest<T> _test;
protected MyController(ITest<T> test)
{
_test = test;
}
}
对于每个实体,我创建一个从MyController继承的控制器,并基于我希望ninject注入特定类的实体
为此,我尝试使用以下绑定:
kernel.Bind(typeof(ITest<>)).To(typeof(Test<>)).InRequestScope();
kernel.Bind(x=>x.FromAssemblyContaining(typeof(Test<>))
.SelectAllClasses()
.InheritedFrom(typeof(Test<>))
.BindToSelf());
不幸的是,我总是犯这样的错误:
激活ITest{Tool}时出错
没有匹配的绑定可用,并且类型不可自绑定。
激活路径:
2将依赖项ITest{Tool}注入ToolsController类型构造函数的参数测试
1对ToolsController的请求
建议:1确保已为定义了绑定
ITest{Tool}。2如果绑定是在模块中定义的,请确保
模块已加载到内核中。3.确保你没有
意外创建了多个内核。4如果您正在使用
构造函数参数,请确保参数名称与
构造函数参数名。5如果您使用的是自动模块
加载时,请确保搜索路径和筛选器正确
我如何告诉Ninject在实体类型的基础上注入类 当前编写的代码无法工作 您有两个选择: 使用泛型: 因为您的控制器期望ITest绑定到无法实例化的抽象类测试 您必须进行一个具体但通用的类测试,并为ApplicationDbContext添加一个绑定,该绑定将自动工作 使用反射在绑定时查找正确的类型,例如: 重要的!!!删除两个内核.Bind调用 注:方法2目前假设所有模型和测试衍生工具分别在一个假设中。如果不是这样,您需要添加更多的反射魔法来检查所有引用的程序集
在此之后,控制器将被重新测试注入。尽管对你说实话,方法1。更好的方法是:异常文本引用列表中不存在的类ToolsController。你能给我看一下吗?另外,请给我看一下TestI的构造器。我编辑了我的帖子,现在可以看到构造器了。我正在寻找一种拥有bacth绑定方法的方法,因为我有50多个实体。
// this will find classes which, like RepoTest, are derived from Test<>
var allDerivedTypes = typeof(Test<>).Assembly.GetExportedTypes().Where(x => x.BaseType.IsGenericType && x.BaseType.GetGenericTypeDefinition() == typeof(Test<>)).ToList();
// ideally, you'd find some way to constrain all your models.
// what you need for this foreach is all of the entities that can be present in things like RepoTest
foreach(var t in typeof(Tool).Assembly.GetExportedTypes())
{
// For each entity, get a runtime representation of Test<Entity>
var targetType = typeof(Test<>).MakeGenericType(t);
// Check if there is a class derived from Test<Entity>
var potentiallyPresentImplementation = allDerivedTypes.FirstOrDefault(x => targetType == x.BaseType); // here you might want to decide how to handle multiple instances of the same generic base
// Found one, so bind it
if(potentiallyPresentImplementation != null)
{
kernel.Bind(targetType ).To(potentiallyPresentImplementation ).InRequestScope();
}
}