[英]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.