• 自制简单实用IoC


     IoC是个好东西,但是为了这个功能而使用类似 Castle 这种大型框架的话,感觉还是不大好

      代码是之前写的,一直没详细搞,今天整理了一下,感觉挺实用的.

    IoC定义接口:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace System
    {
        /// <summary>
        /// 一个接口,支持IoC定义
        /// </summary>
        public interface IIoCDefine
        {
            /// <summary>
            /// 定义类型
            /// </summary>
            /// <param name="type"></param>
            /// <param name="implType"></param>
            void Define(Type type, Type implType);
            /// <summary>
            /// 定义类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="Impl"></typeparam>
            void Define<T, Impl>() where Impl : T;
        }
    }

    IoC解析接口:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace System
    {
        /// <summary>
        /// 一个接口,支持IoC解析
        /// </summary>
        public interface IIoCResolve
        {
    
            /// <summary>
            /// 解析类型
            /// </summary>
            /// <param name="type"></param>
            object Resolve(Type type);
            /// <summary>
            /// 解析类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            T Resolve<T>();
        }
    }

    具体实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace System
    {
        /// <summary>
        /// 支持定义解析
        /// </summary>
        internal class ResolveBase : IIoCResolve, IIoCDefine
        {
    
            ICache<Type, Type> _typeMaps = CacheFactory.CreateCache<Type, Type>();
    
    
            ICache<string, Type> _genericTypeMaps = CacheFactory.CreateCache<string, Type>();
    
            /// <summary>
            /// 定义类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="Impl"></typeparam>
            public void Define<T, Impl>() where Impl : T
            {
                Define(typeof(T), typeof(Impl));
            }
    
            /// <summary>
            /// 定义类型
            /// </summary>
            /// <param name="type"></param>
            /// <param name="implType"></param>
            public void Define(Type type, Type implType)
            {
                if (type == null)
                {
                    throw Error.ArgumentNullException("type");
                }
                if (implType == null)
                {
                    throw Error.ArgumentNullException("implType");
                }
    
                if (implType.IsInterface || implType.IsAbstract)
                {
                    throw Error.ArgumentException("不能是抽象类型或接口", "implType");
                }
    
    
                if (!type.IsGenericTypeDefinition == implType.IsGenericTypeDefinition)
                {
                    throw Error.ArgumentException("泛型不能与非泛型互转", "implType");
                }
    
    
                if (!implType.IsGenericTypeDefinition && !type.IsAssignableFrom(implType) && !type.GetTypeInfo().IsAssignableFrom(implType))
                {
                    throw Error.ArgumentException("不是子类", "implType");
                }
    
    
                _typeMaps[type] = implType;
    
                if (type.IsGenericType)
                {
                    _genericTypeMaps[GetGenericTypeDefinitionKey(type)] = implType;
                }
    
            }
    
            string GetGenericTypeDefinitionKey(Type type)
            {
    
                //  var temp = _typeMaps.Keys.FirstOrDefault(o => o.IsGenericType && o.Name == type.Name && o.Namespace == o.Namespace && o.Module.Equals(type.Module));
                //return type.Name + "_" + type.Namespace + "_" + type.Module.Name;
    
                return type.FullName + "_" + type.Module.Name;
            }
    
            /// <summary>
            /// 得到类型实例
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public T Resolve<T>()
            {
                Type type = typeof(T);
    
                return (T)Resolve(type);
            }
    
            /// <summary>
            /// 得到类型实例
            /// </summary>
            /// <returns></returns>
            public object Resolve(Type type)
            {
    
                var instanceType = GetInstanceType(type);
    
                //if (instanceType.IsAbstract || instanceType.IsInterface)
                //{
                //    throw Error.ArgumentException("解析失败 : 不能是接口或抽象类");
                //}
    
    
                return ActivatorCache.CreateInstance(instanceType);
    
                // return Activator.CreateInstance(instanceType);
            }
    
            /// <summary>
            /// 得到解析类型
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            Type GetInstanceType(Type type)
            {
                if (type == null)
                {
                    throw Error.ArgumentNullException("type");
                }
                Type instanceType;
    
                if (!type.IsGenericType)
                {
                    //如果非泛型,直接拿缓存
                    instanceType = _typeMaps[type];
                    if (instanceType == null)
                    {
                        throw Error.ArgumentException("解析失败 : 未定义解析类型");
                    }
                    return instanceType;
                }
    
    
                //是泛型
                instanceType = _genericTypeMaps[GetGenericTypeDefinitionKey(type)];
    
                if (instanceType == null)
                {
                    if (type.IsGenericTypeDefinition)
                    {
                        throw Error.ArgumentException("解析失败 : 未定义解析类型");
                    }
                    //找不到具体泛型类型
                    //从泛型定义中找
                    var genericType = type.GetGenericTypeDefinition();
                    instanceType = _genericTypeMaps[GetGenericTypeDefinitionKey(genericType)];
                    if (instanceType == null)
                    {
                        throw Error.ArgumentException("解析失败 : 未定义解析类型");
                    }
                    instanceType = instanceType.MakeGenericType(type.GenericTypeArguments);
                }
    
    
    
                if (type.IsGenericTypeDefinition)
                {
                    //指定泛型参数类型
                    var gType = instanceType.MakeGenericType(type.GenericTypeArguments);
                    instanceType = gType;
                }
    
                return instanceType;
            }
    
    
            //bool Equals(Type[] types1, Type[] types2)
            //{
            //    if (types1 == null || types2 == null)
            //    {
            //        return false;
            //    }
            //    if (types1.Length != types2.Length)
            //    {
            //        return false;
            //    }
    
    
            //    int length = types1.Length;
    
            //    for (int i = 0; i < length; i++)
            //    {
            //        var type1 = types1[i];
            //        var type2 = types2[i];
    
            //        if (!types1.Equals(type2) && !(type1.IsAssignableFrom(type2) || type2.IsAssignableFrom(type1)))
            //        {
            //            return false;
            //        }
    
            //    }
    
            //    return true;
    
            //}
    
    
    
            public object Resolve(Type type, params object[] values)
            {
                var instanceType = GetInstanceType(type);
    
                if (instanceType.IsAbstract || instanceType.IsInterface)
                {
                    throw Error.ArgumentException("解析失败 : 不能是接口或抽象类");
                }
    
                var types = values.Select(o => o.GetType()).ToArray();
    
    
                return ActivatorCache.CreateInstance(instanceType, values);
    
                // return Activator.CreateInstance(instanceType, values);
            }
    
            public T Resolve<T>(params object[] values)
            {
    
                return (T)Resolve(typeof(T), values);
            }
        }
    }
    View Code

    给个入口:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace System
    {
    
        /// <summary>
        /// IoC入口对象
        /// </summary>
        public sealed class IoCManager : IIoCResolve, IIoCDefine
        {
            IoCManager()
            {
                var resolve = new ResolveBase();
                _resolve = resolve;
                _define = resolve;
            }
    
    
            public static readonly IoCManager Instance = new IoCManager();
    
    
            IIoCResolve _resolve;
    
            IIoCDefine _define;
    
            /// <summary>
            /// 定义类型
            /// </summary>
            /// <param name="type"></param>
            /// <param name="implType"></param>
            public void Define(Type type, Type implType)
            {
                _define.Define(type, implType);
            }
    
            /// <summary>
            /// 定义类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="Impl"></typeparam>
            public void Define<T, Impl>() where Impl : T
            {
                _define.Define<T, Impl>();
            }
    
    
            /// <summary>
            /// 解析类型
            /// </summary>
            /// <param name="type"></param>
            /// <param name="implType"></param>
            public object Resolve(Type type)
            {
                return _resolve.Resolve(type);
            }
    
            /// <summary>
            /// 解析类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="Impl"></typeparam>
            public T Resolve<T>()
            {
                return _resolve.Resolve<T>();
            }
    
    
        }
    }

    到这里就大功告成了!!!

    测试:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Dai.CommonLib.Tests.Models
    {
        public interface TestInterface
        {
        }
    
        public interface TestInterface<T>:TestInterface
        {
        }
    
        class TestClass : TestInterface
        {
    
        }
    
    
        class TestClass<T> : TestInterface<T>
        {
    
        }
    
        class TestClass1<T> : TestClass<T>
        {
    
        }
    
    
    }
          [TestMethod]
            public void TestMethod2()
            {
    
                IoCManager.Instance.Define(typeof(TestInterface), typeof(TestClass<decimal>));
    
                IoCManager.Instance.Define(typeof(TestInterface<>), typeof(TestClass<>));
    
                IoCManager.Instance.Define(typeof(TestInterface<string>), typeof(TestClass1<string>));
    
                var model = IoCManager.Instance.Resolve<TestInterface>();
    
                var model1 = IoCManager.Instance.Resolve<TestInterface<int>>();
    
                var model2 = IoCManager.Instance.Resolve<TestInterface<string>>();
    
                Assert.IsTrue(model is TestClass<decimal>);
    
                Assert.IsTrue(model1 is TestClass<int>);
    
                Assert.IsTrue(model2 is TestClass1<string>);
    
                IoCManager.Instance.Define(typeof(TestInterface), typeof(TestClass));
    
                var model3 = IoCManager.Instance.Resolve<TestInterface>();
    
                Assert.IsTrue(model3 is TestClass);
            }

    优点: 支持泛型,如果指定了具体的泛型类型,那优先解析具体类型,否则从泛型类型定义中替换具体泛型类型参数,如上面的代码的 TestClass和TestClass1类型

    下次写个Aop Inject 静态编织注入的文章

  • 相关阅读:
    在Linux下OpenCV的下载和编译
    安装GDB-ImageWatch ,在QT中查看图像
    linux下对qt编写的程序进行部署
    GOQTTemplate简单介绍
    寻找激光的交叉点
    基于opencv和QT的摄像头采集代码( GoQTtemplate3持续更新)
    图像处理工程师的要求研究
    如何将QT的pro图标修改的更显著一些
    快速阅读《QT5.9 c++开发指南》2
    小米盒子连接老式电脑显示器(VGA接口)
  • 原文地址:https://www.cnblogs.com/pokemon/p/5479162.html
Copyright © 2020-2023  润新知