asp.net core mvc中修改DefaultControllerFactory的CreateController方法中的ControllerContext

Modify ControllerContext in CreateController method of DefaultControllerFactory in asp.net core mvc

但问题是我需要将所有依赖项传递给控制器​​构造函数。

 public class CustomControllerFactory: DefaultControllerFactory
{  
    public CustomControllerFactory(ICatalogModelFactory catalogModelFactory,
        IProductModelFactory productModelFactory,
        IControllerActivator controllerActivator, IEnumerable<IControllerPropertyActivator> propertyActivators)
        :base(controllerActivator, propertyActivators)
    {
        this._catalogModelFactory = catalogModelFactory;
        this._productModelFactory = productModelFactory;
    }
    public override object CreateController(ControllerContext context)
    {
        if (context.ActionDescriptor.ControllerTypeInfo.AsType() == typeof(CatalogController))
        {
            return new CatalogCustomController(_catalogModelFactory,
            _productModelFactory,
            _categoryService, 
        }

        return base.CreateController(context);
    }
}

虽然我想做这样的事情,通过修改 ControllerContext上下文

 public override object CreateController(ControllerContext context)
    {
        if (context.ActionDescriptor.ControllerTypeInfo.AsType() == typeof(CatalogController))
        {

            context.ActionDescriptor.ControllerName = "CatalogCustomController";   
        }

        return base.CreateController(context);
    }

您可以尝试将 Controller 注册到 IServiceCollection,然后从 CreateController 中的 IServiceCollection 检索 Controller

  1. AddControllersAsServices

    的扩展方法
    public static class Extension
    {
    public static IMvcBuilder AddControllersAsServices(this IMvcBuilder builder)
    {
        var feature = new ControllerFeature();
        builder.PartManager.PopulateFeature(feature);
    
        foreach (var controller in feature.Controllers.Select(c => c.AsType()))
        {
            builder.Services.TryAddTransient(controller, controller);
        }
    
        builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
    
        return builder;
    }
    }
    
  2. 注册服务

        services.AddMvc()
            .AddControllersAsServices();
    
  3. CustomControllerFactory

     public class CustomControllerFactory : DefaultControllerFactory
     {
    public CustomControllerFactory(
        IControllerActivator controllerActivator, IEnumerable<IControllerPropertyActivator> propertyActivators)
        : base(controllerActivator, propertyActivators)
    {
    }
    public override object CreateController(ControllerContext context)
    {
        if (context.ActionDescriptor.ControllerTypeInfo.AsType() == typeof(CatalogController))
        {               
            return context.HttpContext.RequestServices.GetRequiredService(typeof(CatalogCustomController));
        }
    
        return base.CreateController(context);
    }
    }
    

我找到了一个解决方案,无需将控制器注册为服务。

  • 从主控制器继承自定义控制器。
  • 在自定义控制器工厂中,获取请求的控制器类型。
  • 将 ControllerTypeInfo 替换为自定义的

public override object CreateController(ControllerContext context)
    {
        Type typeOfController = context.ActionDescriptor.ControllerTypeInfo.UnderlyingSystemType;

if (typeOfController == typeof(Nop.Web.Controllers.CatalogController)) { context.ActionDescriptor.ControllerTypeInfo = typeof(Controllers.CatalogCustomController).GetTypeInfo(); } else if (typeOfController == typeof(Nop.Web.Areas.Admin.Controllers.ProductController)) { context.ActionDescriptor.ControllerTypeInfo = typeof(Areas.Admin.Controllers.ProductCustomController).GetTypeInfo(); } return base.CreateController(context); }<pre>