asp.net core mvc中修改DefaultControllerFactory的CreateController方法中的ControllerContext
Modify ControllerContext in CreateController method of DefaultControllerFactory in asp.net core mvc
- 我想覆盖我的控制器方法。在这里,如果请求到来,我已经将 DefaultControllerFactory 的 CreateController 方法覆盖为 return 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);
}
您可以尝试将 Controller
注册到 IServiceCollection
,然后从 CreateController
中的 IServiceCollection
检索 Controller
。
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 替换为自定义的
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>
- 我想覆盖我的控制器方法。在这里,如果请求到来,我已经将 DefaultControllerFactory 的 CreateController 方法覆盖为 return 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);
}
您可以尝试将 Controller
注册到 IServiceCollection
,然后从 CreateController
中的 IServiceCollection
检索 Controller
。
的扩展方法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 替换为自定义的
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>