我有以下情况:
界面:
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 {工具}时出错 没有匹配的绑定可用,并且该类型不可自绑定。 激活路径: 2)将依赖项ITest {Tool}注入到ToolsController类型的构造函数的参数测试中 1)对ToolsController的请求
建议:1)确保您已为其定义了绑定 ITEST {}工具。 2)如果在模块中定义了绑定,请确保 模块已加载到内核中。 3)确保你没有 不小心创建了多个内核。 4)如果你正在使用 构造函数参数,确保参数名称匹配 构造函数参数名称。 5)如果您使用的是自动模块 加载,确保搜索路径和过滤器正确无误。
如何告诉Ninject,在实体类型上注入类?
答案 0 :(得分:1)
目前编写的代码无法正常工作。
您有两种选择:
因为您的控制器期望绑定到ITest<T>
类abstract
的{{1}}无法实例化。
你必须制作一个具体但通用的类Test<T>
并为Test<T>
添加一个自动生效的绑定。
重要!!!删除两个ApplicationDbContext
来电。
kernel.Bind()
注意:方法2目前假设所有模型和 // 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();
}
}
衍生物都是一个可分辨的。如果不是这种情况,您需要添加一点反射魔法来检查所有引用的组件。
此后,控制器将注入Test<>
。虽然老实说,方法1.更好:)