Измените 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
,
Метод расширения для
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; } }
Регистрация Услуги
services.AddMvc() .AddControllersAsServices();
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>