Asp.net web form 使用IOC(Unity) 构造函数注入Page,.net Framework 4.7.2

    public static class UnityAdapter
    {
        private static object _lock = new object();

        /// <summary>
        /// Add a new Unity container in asp.net application. If there is WebObjectActivator already registered,
        /// it will be chained up. When the new WebObjectActivator can't resolve the type, the previous WebObjectActivator
        /// will be used. If the previous WebObjectActivator can't resolve it either, DefaultCreateInstance will be used
        /// which creates instance through none public default constructor based on reflection.
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer AddUnity()
        {
            lock (_lock)
            {
                HttpRuntime.WebObjectActivator = new ContainerServiceProvider(HttpRuntime.WebObjectActivator);
                
                return GetContainer();
            }
        }

        /// <summary>
        /// Get most recent added Unity container
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer GetContainer()
        {
            return (HttpRuntime.WebObjectActivator as ContainerServiceProvider)?.Container;
        }
    }
    public static class HttpApplicationExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="application"></param>
        /// <returns></returns>
        public static UnityContainer AddUnity(this HttpApplication application)
        {
            if (application == null)
            {
                throw new ArgumentNullException(nameof(application));
            }

            return (UnityContainer)UnityAdapter.AddUnity();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer GetUnityContainer(this HttpApplication application)
        {
            return UnityAdapter.GetContainer();
} }

 

    class ContainerServiceProvider : IServiceProvider, IRegisteredObject
    {
        private const int TypesCannontResolveCacheCap = 100000;
        private readonly IServiceProvider _next;
        private readonly ConcurrentDictionary<Type, bool> _typesCannotResolve = new ConcurrentDictionary<Type, bool>();

        public ContainerServiceProvider(IServiceProvider next)
        {
            _next = next;
            HostingEnvironment.RegisterObject(this);
        }

        /// <summary>
        /// Implementation of IServiceProvider. Asp.net will call this method to
        /// create the instances of Page/UserControl/HttpModule etc.
        /// </summary>
        /// <param name="serviceType"></param>
        /// <returns></returns>
        public object GetService(Type serviceType)
        {
            //
            // Try unresolvable types
            if (_typesCannotResolve.ContainsKey(serviceType))
            {
                return DefaultCreateInstance(serviceType);
            }

            //
            // Try the container
            object result = null;

            try
            {
                result = Container.Resolve(serviceType);
            }
            catch (ResolutionFailedException)
            {
                // Ignore and continue
            }

            //
            // Try the next provider
            if (result == null)
            {
                result = _next?.GetService(serviceType);
            }

            //
            // Default activation
            if (result == null)
            {
                if ((result = DefaultCreateInstance(serviceType)) != null)
                {
                    // Cache it
                    if (_typesCannotResolve.Count < TypesCannontResolveCacheCap)
                    {
                        _typesCannotResolve.TryAdd(serviceType, true);
                    }
                }
            }

            return result;
        }

        public IUnityContainer Container { get; internal set; } = new UnityContainer();

        public void Stop(bool immediate)
        {
            HostingEnvironment.UnregisterObject(this);

            Container.Dispose();
        }

        internal IServiceProvider NextServiceProvider
        {
            get { return _next; }
        }

        internal IDictionary<Type, bool> TypeCannotResolveDictionary
        {
            get { return _typesCannotResolve; }
        }

        protected virtual object DefaultCreateInstance(Type type)
        {
            return Activator.CreateInstance(
               type,
               BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance,
               null,
               null,
               null);
        }
    }

  引入上面这三个类,然后用nuget 安装UnityIOC,然后在Application_Start中配置

 

  运行效果如下:

 

posted @ 2020-08-04 17:49  夏风微凉  阅读(279)  评论(0编辑  收藏  举报