如何在Unity.Mvc IoC容器中注册从基类继承的所有类?
作者:互联网
我有一个使用c#在ASP.NET MVC 5框架顶部编写的应用程序.
我有以下属性用于装饰控制器
namespace Plugin1.Helpers
{
public class PermissionAttribute : MainApp.Helpers.BasePermissionClass
{
public PermissionAttribute()
{
}
public PermissionAttribute(string key)
: base(key, "MVC")
{
}
public PermissionAttribute(string[] keys)
: base(keys, "MVC")
{
}
}
}
这是Permission属性用于装饰控制器的方式
namespace Plugin1.Controllers
{
[Plugin1.Helpers.Permission(Keys = "some key")]
public class HomeController : Controller
{
// ....
}
}
不幸的是,每次尝试从IoC容器解析控制器时,都会出现以下错误.
The type PermissionAttribute has multiple constructors of length 1.
Unable to disambiguate.
但是,当我为每个PermissionAttribute类手动添加以下行时,一切正常
container.RegisterType<Plugin1.Helpers.PermissionAttribute>(new InjectionConstructor());
container.RegisterType<PluginXYZ.Helpers.PermissionAttribute>(new InjectionConstructor());
但是,我有一个可插入的基本应用程序,并且每个插件都有一个不同的PermissionAttribute类.我没有让每个插件手动将其自己的PermissionAttribute类注册到容器中,而是尝试使用反射来查找从MainApp.Helpers.BasePermissionClass继承的任何类,并在首次启动应用程序时简单地注册它.
在我的MainApp项目中,我首先搜索MainProject.Helpers.BasePermissionClass子类的任何类型,然后通过提供新的InjectionConstructor()进行注册,它应该告诉Unity使用无参数构造函数.
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(x => x.IsClass && !x.IsInterface && !x.IsAbstract && x.IsSubclassOf(typeof(BasePermissionClass))).ToList();
foreach(Type type in types)
{
container.RegisterType(typeof(BasePermissionClass), type, type.FullName, new InjectionConstructor());
}
我通过手动评估已注册的对象来验证是否已找到类型并将其注册在容器中.
我也尝试注册像这样的类型
foreach(Type type in types)
{
container.RegisterType(type.GetType(), type, type.FullName, new InjectionConstructor());
}
但这引发了以下异常
The type Plugin1.Helpers.PermissionAttribute cannot be assigned to variables
of type System.RuntimeType.
Parameter name: typeFrom
如何使用反射来正确注册从BasePermissionClass继承的任何类
如何正确将每个类注册为它的类型而不是基本类型.
解决方法:
为什么会看到此错误?
The type Plugin1.Helpers.PermissionAttribute cannot be assigned to
variables of type System.RuntimeType. Parameter name: typeFrom
这是因为.GetType()方法返回System.RuntimeType而不是实现的类型.
此外,您不需要获取类型的类型.您的类型变量是类型类型.
相反,尝试像这样注册您的课程
var objs = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(x => x.IsClass && !x.IsInterface && !x.IsAbstract && x.IsSubclassOf(typeof(BasePermissionClass))).ToList();
foreach(Type obj in objs)
{
container.RegisterType(obj, new InjectionConstructor());
}
由于您仅注册实现,因此无需使用密钥注册对象.
标签:reflection,asp-net-mvc-5,unity-container,c,ioc-container 来源: https://codeday.me/bug/20191109/2011792.html