Измените ControllerContext в методе CreateController метода DefaultControllerFactory в ядре asp.net mvc

  • Я хочу переопределить мой метод контроллеров. Здесь я переопределил метод CreateController метода DefaultControllerFactory для возврата объекта CatalogCustomController, если запрос приходит для CatalogController.

Но проблема здесь в том, что мне нужно передать всю зависимость в конструктор контроллера.

 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);
    }

2 ответа

Решение

Вы можете попробовать зарегистрироваться Controller в IServiceCollectionи затем получить Controller от IServiceCollection в CreateController,

  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 на пользовательский

 открытый объект переопределения CreateController(контекст ControllerContext)
    {
        Тип 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>
Другие вопросы по тегам