欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

3、手写Unity容器--第N层依赖注入

程序员文章站 2022-06-04 09:54:28
这个场景跟《手写Unity容器--极致简陋版Unity容器》不同,这里构造AndroidPhone的时候,AndroidPhone依赖于1个IPad 1、IPhone接口 2、AndroidPhone实现 3、IPad接口 4、IPad实现 5、IHeadPhone接口 6、IHeadPhone实现 ......

这个场景跟《手写unity容器--极致简陋版unity容器》不同,这里构造androidphone的时候,androidphone依赖于1个ipad

 3、手写Unity容器--第N层依赖注入

3、手写Unity容器--第N层依赖注入

1、iphone接口

namespace simplestunity_nlayer
{
    interface iphone
    {
        void call();
    }
}

2、androidphone实现

namespace simplestunity_nlayer
{
    public class androidphone : iphone
    {
        public androidphone(ipad ipad, iheadphone iheadphone)
        {
            console.writeline("{0}构造函数", this.gettype().name);
        }
    }
}

3、ipad接口

namespace simplestunity_nlayer
{
    public interface ipad
    {
        void show();
    }
}

4、ipad实现

namespace simplestunity_nlayer
{
    public class androidpad:ipad
    {
        public androidpad()
        {
            console.writeline("{0}构造函数", this.gettype().name);
        }

        public void show()
        {
            console.writeline("看{0}", this.gettype().name);
        }
    }
}

5、iheadphone接口

namespace simplestunity_nlayer
{
    public interface iheadphone
    {
        
    }
}

6、iheadphone实现

namespace simplestunity_nlayer
{
    public class headphone : iheadphone
    {
        public headphone(irootphone irootphone)
        {
            console.writeline("headphone 被构造");
        }
    }
}

7、irootphone接口

namespace simplestunity_nlayer
{
    public interface irootphone
    {
        
    }
}

8、irootphone实现

namespace simplestunity_nlayer
{
    public class rootphone : irootphone
    {
        public rootphone()
        {
            console.writeline("rootphone 被构造");
        }
    }
}

9、容器--接口

public interface idavidcontainer
{
    void registertype<tfrom, tto>();
    
    t resolve<t>();
}

10、容器--实现

namespace simplestunity_nlayer
{
    /// <summary>
    /// 容器--工厂
    /// </summary>
    public class daivdcontainer:idaivdcontainer
    {
        private dictionary<string, type> containerdictionary = new dictionary<string, type>();//字典

        /// <summary>
        /// 注册类型
        /// </summary>
        /// <typeparam name="tfrom"></typeparam>
        /// <typeparam name="tto"></typeparam>
        public void registertype<tfrom, tto>()
        {
            containerdictionary.add(typeof(tfrom).fullname, typeof(tto));
        }

        /// <summary>
        /// 获取实例
        /// </summary>
        /// <typeparam name="t"></typeparam>
        /// <returns></returns>
        public t resolve<t>()
        {
            type type = containerdictionary[typeof(t).fullname];
            return (t)this.createinstance(type);
        }

        private object createinstance(type type)
        {
            //1、得到类型的所有构造函数
            constructorinfo[] ctorarray = type.getconstructors();

            //2、只得到有标记davidinjectionconstructor特性的构造函数,如果都没有标记特性,那么得到参数最多的构造函数
            constructorinfo currentctor = null;

            if (ctorarray.count(c => c.isdefined(typeof(davidinjectionconstructor), true)) > 0)
            {
                currentctor = ctorarray.firstordefault(c => c.isdefined(typeof(davidinjectionconstructor), true));//得到第1个标记davidinjectionconstructor特性的构造函数
            }
            else
            {
                currentctor = ctorarray.orderbydescending(c => c.getparameters().length).firstordefault();//得到参数个数最多的构造函数
            }
            list<object> paralist = new list<object>();
            //递归:隐形的跳出条件,条件就是getparameters结果为空,targettype拥有无参数构造函数
            foreach (var para in currentctor.getparameters())
            {
                //得到的参数类型是ipad,抽象无法创建实例
                var paratype = para.parametertype;
                //所以根据ipad key,得到androidpad类型,具体类型就可以创建实例
                var targetparatype = containerdictionary[paratype.fullname];
                //继续检查targetparatype的构造函数,不能直接创建实例了
                object obj = this.createinstance(targetparatype);
                
                paralist.add(obj);
            }
            return activator.createinstance(type, paralist.toarray());
        }
    }
}

11、调用

class program
{
    static void main(string[] args)
    {
        daivdcontainer davidcontainer = new daivdcontainer();
        davidcontainer.registertype<iphone, androidphone>();
        davidcontainer.registertype<ipad, androidpad>();
        davidcontainer.registertype<iheadphone, headphone>();
        davidcontainer.registertype<irootphone, rootphone>();
        iphone iphone = davidcontainer.resolve<iphone>();
        iphone.call();
    }
}

3、手写Unity容器--第N层依赖注入