实现一个迷你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;
        }
    }
原文地址:https://www.cnblogs.com/fanfan-90/p/13586760.html