zoukankan      html  css  js  c++  java
  • 实现一个迷你IOC容器

    容器接口:

        /// <summary>
        /// Ioc容器接口
        /// </summary>
        public interface IContainer : IServiceProvider, IServiceRegister
        { }
    
        /// <summary>
        /// 服务接口
        /// </summary>
        public interface IServiceProvider
        {
            T Resolve<T>() where T : class;
        }
    
        /// <summary>
        /// 注册服务接口
        /// </summary>
        public interface IServiceRegister
        {
            IServiceRegister Register<T>(Func<IServiceProvider, T> serviceCreator) where T : class;
    
            IServiceRegister Register<T>() where T : class;
        }
    

    容器类:

    public class Container : IContainer
        {
            private readonly IDictionary<string, object> _factoryDict = new Dictionary<string, object>();
            private readonly IDictionary<string, Type> _registrationDict = new Dictionary<string, Type>();
    
            private readonly IDictionary<string, object> _instanceDict = new Dictionary<string, object>();
    
            private static Container _Instance = null;
            public static Container Instance
            {
                get
                {
                    if (_Instance == null)
                    {
                        _Instance = new Container();
                    }
                    return _Instance;
                }
            }
    
            private bool ServiceIsRegistered(string typeName)
            {
                return this._factoryDict.ContainsKey(typeName) || this._registrationDict.ContainsKey(typeName);
            }
    
            public IServiceRegister Register<T>(Func<IServiceProvider, T> ctor) where T : class
            {
                Type type = typeof(T);
                string typeName = type.FullName;
                if (this.ServiceIsRegistered(typeName))
                {
                    return this;
                }
                this._factoryDict.Add(typeName, ctor);
                return this;
            }
    
            public T Resolve<T>() where T : class
            {
                Type serivceType = typeof(T);
    
                string typeName = serivceType.FullName;
    
                if (!this.ServiceIsRegistered(typeName))
                {
                    throw new Exception(string.Format("类型名称 {0} 未被注册!", typeName));
                }
    
                if (!this._instanceDict.ContainsKey(typeName))
                {
                    if (this._registrationDict.ContainsKey(typeName))
                    {
                        Type type = this._registrationDict[typeName];
                        object @object = this.CreateServiceInstance(type);
                        this._instanceDict.Add(typeName, @object);
                    }
    
                    if (this._factoryDict.ContainsKey(typeName))
                    {
                        object @object = ((Func<IServiceProvider, T>)this._factoryDict[typeName])(this);
                        this._instanceDict.Add(typeName, @object);
                    }
                }
    
                return (T)this._instanceDict[typeName];
            }
    
            private object Resolve(Type serviceType)
            {
                return typeof(Container).GetMethod("Resolve", new Type[0]).MakeGenericMethod(serviceType).Invoke(this, new object[0]);
            }
    
            private object CreateServiceInstance(Type type)
            {
                var constructors = type.GetConstructors();
    
                ParameterInfo[] parameterInfos = constructors[0].GetParameters();
                var parameters = parameterInfos.Select(parameterInfo => this.Resolve(parameterInfo.ParameterType)).ToArray();
    
                return constructors[0].Invoke(parameters);
            }
    
            public IServiceRegister Register<T>() where T : class
            {
                Type type = typeof(T);
                string typeName = type.FullName;
    
                if (this.ServiceIsRegistered(typeName))
                {
                    return this;
                }
    
                var constructors = type.GetConstructors();
                if (constructors.Length != 1)
                {
                    throw new Exception(string.Format("注册类型必须至少要有一个构造函数. 目前这个 {0} 类型里面有 {1} 个构造函数", type.Name, constructors.Length.ToString()));
                }
    
                this._registrationDict.Add(typeName, type);
                return this;
            }
        }
    

    使用:

    public static void Main(string[] args)
            {
                Container container = Container.Instance;
                //注册服务
                container.Register<Service1>();
                container.Register(p => new Service2("fan"));
                //解析服务
                var s1 = container.Resolve<Service1>();
                Console.ReadKey();            
            }
        public class Service1 {
            public Service1(Service2 service2)
            {
                var s2 = service2;
                Console.WriteLine(s2.Name);
            }
        }
        public class Service2 {
            public string Name { get; set; }
            public Service2(string name)
            {
                this.Name = name;
            }
        }
    
  • 相关阅读:
    redis面试题总结
    TP5隐藏index.php
    php四种文件加载语句
    【Redis缓存机制】1.Redis介绍和使用场景
    Linux cpufreq 机制了解 arm
    数码设备发展的核心:分离,互联网营销 狼人:
    豆瓣:“慢公司”,互联网营销 狼人:
    互联网周刊:互联网进化论,互联网营销 狼人:
    怀念中国雅虎:技术文化和惨淡命运,互联网营销 狼人:
    菜鸟玩GAE(Google App Engine)完全指南,互联网营销 狼人:
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/13586760.html
Copyright © 2011-2022 走看看