[英]ASP.NET Core 3 - Overriding the default ControllerFactory on custom, how save it call in else cases?
如果 DefaultControllerFactory 已成为 ASP.NET Core 3 中的内部类,如何使用自定义案例的自定义工厂覆盖默认实现 IControllerFactory 并在正常情况下继续调用 DefaultControllerFactory?
services.AddSingleton<IControllerFactory, MyCustomControllerFactory>();
// this class for .NET core 2
public class MyCustomControllerFactory : DefaultControllerFactory
{
public override object CreateController(ControllerContext context)
{
//custom handling...
//base handling
return base.CreateController(context);
}
public override void ReleaseController(ControllerContext context, object controller)
{
base.ReleaseController(context, controller);
}
}
.NET 5 中的 DefaultControllerFactory 类是内部的,我无法调用它的 CreateController 方法来尝试在 ASP MVC Core 5 环境中注册常规控制器。
//this class for .NET core 3 or .NET 5
public class MyCustomControllerFactory : IControllerFactory
{
public object CreateController(ControllerContext context)
{
if(/*is custom case*/)
{
/*custom actions*/
return /*custom IController*/
}
return /*in this place I want calling base.CreateController(context)*/;
}
public void ReleaseController(ControllerContext context, object controller)
{
var disposable = controller as IDisposable;
if (disposable != null) { disposable.Dispose(); }
}
}
我们可以重载 IControllerActivator 或 IControllerFactory。 此方法将始终被调用,从而创建控制器。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IControllerActivator, CustomControllerActivator>();
services.AddMvc(options => { });
}
}
我们仍然可以调用主要的平台函数来创建控制器。 我们只需要获取 IControllerActivator 或 IControllerFactory 的所有已注册实例的列表,并将我们的实现从该列表中一一排除,尝试使用此列表中的每一个创建一个控制器。 重要的是要理解这个实现被尽可能地简化,如果重新添加到 DI 中可以循环。
public class CustomControllerActivator : IControllerActivator
{
private static object CreateController(IEnumerable<IControllerActivator> activators, ControllerContext context)
{
if (activators is null)
{
throw new ArgumentNullException(nameof(activators));
}
foreach (IControllerActivator activator in activators)
{
object controller = activator.Create(context);
if (controller != default)
return controller;
}
return default;
}
private readonly IServiceProvider _provider;
private IEnumerable<IControllerActivator> _otherActivators;
private IEnumerable<IControllerActivator> OtherActivators
{
get
{
if (_otherActivators == null)
_otherActivators = _provider.GetServices<IControllerActivator>()?
.Where(o => !object.ReferenceEquals(this, o));
return _otherActivators;
}
}
public CustomControllerActivator(IServiceProvider provider)
{
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
}
public object Create(ControllerContext controllerContext)
{
if (controllerContext == null)
{
throw new ArgumentNullException(nameof(controllerContext));
}
if (controllerContext.ActionDescriptor == null)
{
throw new ArgumentException(nameof(controllerContext.ActionDescriptor));
}
var controllerTypeInfo = controllerContext.ActionDescriptor.ControllerTypeInfo;
if (controllerTypeInfo == null)
{
throw new ArgumentException(nameof(controllerContext.ActionDescriptor.ControllerTypeInfo));
}
if (!IsNeedThisCustomController(controllerContext))
return CreateController(OtherActivators, controllerContext);
return CreateCustomController(controllerContext);
}
/// <summary>
/// Do need to create this custom controller
/// </summary>
/// <param name="controllerContext"></param>
/// <returns></returns>
private bool IsNeedThisCustomController(ControllerContext controllerContext)
{
return false;
}
/// <summary>
/// Сreating a custom controller
/// </summary>
/// <param name="controllerContext"></param>
/// <returns></returns>
private object CreateCustomController(ControllerContext controllerContext)
{
return default;
}
public void Release(ControllerContext context, object controller)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (controller == null)
{
throw new ArgumentNullException(nameof(controller));
}
if (controller is IDisposable disposable)
{
disposable.Dispose();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.