繁体   English   中英

ASP.NET Core 3 - 覆盖自定义的默认 ControllerFactory,在其他情况下如何保存它调用?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM