码迷,mamicode.com
首页 > 其他好文 > 详细

自制简单实用IoC

时间:2016-05-10 20:51:42      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

 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 静态编织注入的文章

自制简单实用IoC

标签:

原文地址:http://www.cnblogs.com/pokemon/p/5479162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!