vendredi 6 avril 2018

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 my 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 I use it to decorate my controllers

namespace Plugin1.Controllers { [Plugin1.Helpers.Permission(Keys = "some key")] public class HomeController : Controller { // .... } }

But I get this error each time I try to resolve the controller

The type PermissionAttribute has multiple constructors of length 1. Unable to disambiguate.

When I manually add this for each PermissionAttribute class, everything working perfectly

container.RegisterType<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 && !obj.IsAbstract && obj.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.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





Aucun commentaire:

Enregistrer un commentaire