如何解决ASP.NET Core 3 - 覆盖自定义的默认 ControllerFactory,在其他情况下如何保存它调用?
如果 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();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。