简体   繁体   中英

How to register all classes that inherits from a base class in Unity.Mvc IoC container?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM