【问题标题】:MVC: How to get the controllers and their dependencies at runtimeMVC:如何在运行时获取控制器及其依赖项
【发布时间】:2014-07-29 09:16:18
【问题描述】:

所以我正在构建一个可通过插件扩展的 MVC Web 应用程序。 插件可以放到一个文件夹中,如果应用程序重新启动,它们就会被加载。我遇到的问题是插件中的一些/大部分控制器都有带参数的构造函数。 我已经有一个自定义控制器工厂,可以在运行时创建必要的控制器,但问题在于控制器的注册。 我目前有:

CustomControllerFactory factory = new CustomControllerFactory();
factory.RegisterFactoryMethod<MyController>(() => new MyController(_myDependecy));

控制器工厂为:

public class CustomControllerFactory : DefaultControllerFactory
{

    private Dictionary<string, Func<IController>> _factoryMethods = new Dictionary<string, Func<IController>>();

    public void RegisterFactoryMethod<T>(Func<IController> factoryMethod)
                where T : IController
    {
        string controllerName = ConvertToControllerName<T>();

        if (_factoryMethods.ContainsKey(controllerName))
            throw new Exception(String.Format("FactoryMethod for controller '{0}'is already registered.", controllerName));

        _factoryMethods[controllerName] = factoryMethod;
    }


    private string ConvertToControllerName<T>()
    {
        string fullName = typeof (T).Name;
        //Cut of "Controller"
        return fullName.Substring(0, fullName.Length - 10);
    }

    public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {

        if (_factoryMethods.ContainsKey(controllerName))
            return _factoryMethods[controllerName]();

        return base.CreateController(requestContext, controllerName);

    }
}

但这需要我知道在编译时要添加哪些控制器以及哪些依赖项。 如何在运行时从它们的程序集中获取控制器及其依赖项?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-4 plugins


    【解决方案1】:

    我最终找到了一个解决方案,但它并不完全通用,因为我只考虑了具有已知依赖关系的构造函数。

    Type[] controllers = assembly.GetTypes().Where(x => x.BaseType == typeof(Controller)).ToArray();
    foreach (Type controller in controllers)
        {
            ConstructorInfo[] constructors = controller.GetConstructors();
    
            foreach (var constructor in constructors)
            {
                RegisterControllerConstructor(constructor,_MyDependecy,controller,factory);
            }
        }
    }
    
    private void RegisterControllerConstructor(ConstructorInfo constructor, MyDependecy _MyDependecy, Type controller, CustomControllerFactory factory)
        {
            ParameterInfo[] parameters = constructor.GetParameters();
            Type[] paraTypes = parameters.Select(p => p.ParameterType).ToArray();
            MethodInfo method =
                factory.GetType().GetMethod("RegisterFactoryMethod").MakeGenericMethod(controller);
            if (paraTypes.Length == 1 && paraTypes[0] == _MyDependecy.GetType())
            {
                var param = new object[1];
    
                Func<IController> action = () =>
                {
                    return Activator.CreateInstance(controller, _MyDependecy) as IController;
                };
    
                param[0] = action;
    
                method.Invoke(factory, param);
    
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 2022-07-29
      • 1970-01-01
      相关资源
      最近更新 更多