I have an app that is written using c# on the top of ASP.NET MVC 5 framework.
I have the following attribute which is used to decorate the controllers with
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")
{
}
}
}
Here is how the Permission
attribute is used it to decorate the controllers
namespace Plugin1.Controllers
{
[Plugin1.Helpers.Permission(Keys = "some key")]
public class HomeController : Controller
{
// ....
}
}
Unfortunately, I get the following error each time I try to resolve the controller from the IoC
container.
The type PermissionAttribute has multiple constructors of length 1. Unable to disambiguate.
However, when I manually add the following line for each PermissionAttribute
class, everything works perfectly
container.RegisterType<Plugin1.Helpers.PermissionAttribute>(new InjectionConstructor());
container.RegisterType<PluginXYZ.Helpers.PermissionAttribute>(new InjectionConstructor());
However, I have a plugable base app, and each plugin has a different PermissionAttribute
class. Instead of having each plugin manually registering its own PermissionAttribute
class into the container, I am trying to use reflection to find any class the inherits from MainApp.Helpers.BasePermissionClass
and simply register it when the app is first booted.
In my MainApp
project, I first search for any type that is a sub-class-of MainProject.Helpers.BasePermissionClass
and then register it by providing the new InjectionConstructor()
which should tell Unity to use the parameter-less constructor.
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());
}
I verified that the types are found and being registered in the container by manually evaluating the registered objects.
I also tried to register the types like so
foreach(Type type in types)
{
container.RegisterType(type.GetType(), type, type.FullName, new InjectionConstructor());
}
But this is throwing the following exception
The type Plugin1.Helpers.PermissionAttribute cannot be assigned to variables of type System.RuntimeType. Parameter name: typeFrom
How can I use reflection to properly register any class that inherits from BasePermissionClass
How can I correctly register each class to it's type not to the base type.
Why are you seeing this error?
The type Plugin1.Helpers.PermissionAttribute cannot be assigned to variables of type System.RuntimeType. Parameter name: typeFrom
That's because the .GetType()
method returns System.RuntimeType
not the type of your implementation.
Additionally, you should not need to get the type of the type. Your type
variable is of a type Type
.
Instead, try registering your classes like so
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());
}
Since your only registering implementation, you don't need to register the object with a key.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.