欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC-創(chuàng)新互聯(lián)

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

前言

在前面的篇幅中對(duì)依賴(lài)倒置原則和IoC框架的使用只是做了個(gè)簡(jiǎn)單的介紹,并沒(méi)有很詳細(xì)的去演示,可能有的朋友還是區(qū)分不了依賴(lài)倒置、依賴(lài)注入、控制反轉(zhuǎn)這幾個(gè)名詞,或許知道的也只是知道依賴(lài)倒置是原則,依賴(lài)注入、控制反轉(zhuǎn)都是實(shí)現(xiàn)的方式,我將在下面對(duì)這些個(gè)名詞做詳細(xì)的介紹,在篇幅的最后還會(huì)自己實(shí)現(xiàn)了IoC容器的功能。

在無(wú)極等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需求定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣,外貿(mào)網(wǎng)站建設(shè),無(wú)極網(wǎng)站建設(shè)費(fèi)用合理。

依賴(lài)倒置原則

我們先來(lái)看一段代碼,代碼1-1

    public class Top
    {
        public void Execution()
        {
            Underly underly = new Underly();
            underly.WriterLine();
        }
    }

    public class Underly
    {
        public void WriterLine()
        {
            Console.WriteLine("這是底層類(lèi)型的輸出");
        }
    }

從代碼1-1中看到Top類(lèi)型的Execution()方法中包含了對(duì)Underly的依賴(lài),直接使用的New來(lái)實(shí)例化Underly類(lèi)型,致使兩個(gè)類(lèi)型之間的耦合是屬于強(qiáng)耦合類(lèi)型,這樣做會(huì)導(dǎo)致在需求發(fā)生變化的時(shí)候?qū)τ诘讓宇?lèi)型也就是Underly的修改會(huì)牽動(dòng)到Top中的現(xiàn)實(shí),而我們是不希望這種事情發(fā)生。

這個(gè)時(shí)候我們?cè)倏?strong>依賴(lài)原則的定義(度娘的):

A.高層次的模塊不應(yīng)該依賴(lài)于低層次的模塊,他們都應(yīng)該依賴(lài)于抽象。

B.抽象不應(yīng)該依賴(lài)于具體,具體應(yīng)該依賴(lài)于抽象。

A.高層次的模塊不應(yīng)該依賴(lài)于低層次的模塊,他們都應(yīng)該依賴(lài)于抽象

對(duì)于A,照著字面意思來(lái)說(shuō)的話(huà)很簡(jiǎn)單了,已經(jīng)沒(méi)法辦再用文字來(lái)描述了,看代碼吧,

代碼1-2

    public class Top
    {
        public void Execution()
        {
            IUnderly underly = new Underly();
            underly.WriterLine();
        }
    }

    public interface IUnderly
    {
        void WriterLine();
    }

    public class Underly:IUnderly
    {
        public void WriterLine()
        {
            Console.WriteLine("這是底層類(lèi)型的輸出");
        }
    }

在代碼1-2中我們對(duì)Underly進(jìn)行了抽象,并且讓其依賴(lài)于抽象(也就是實(shí)現(xiàn)接口),而在Top類(lèi)型中也依賴(lài)于抽象了。

圖1

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

圖1中所示的就是代碼1-2所要表示的類(lèi)型結(jié)構(gòu)了,也就是依賴(lài)倒置原則中A的實(shí)現(xiàn),從圖1中我們可以看到依賴(lài)倒置原則里還裝著開(kāi)放封閉原則,這里所要說(shuō)明的意思就是依賴(lài)倒置原則是開(kāi)放封閉原則的基礎(chǔ)。

從圖1中的結(jié)構(gòu)來(lái)看,如果是站在開(kāi)放封閉原則的角度來(lái)看也是沒(méi)有問(wèn)題的,對(duì)擴(kuò)展開(kāi)放對(duì)修改關(guān)閉,在需求變動(dòng)的時(shí)候只要重新實(shí)現(xiàn)個(gè)依賴(lài)于抽象的下層,利用多態(tài)則可實(shí)現(xiàn)對(duì)擴(kuò)展開(kāi)放。

如果是站在依賴(lài)倒置原則的角度去看,那就是符合了依賴(lài)倒置原則定義的A條。

(Ps:這里有的朋友可能會(huì)說(shuō)上面的示例中Top也依賴(lài)于具體了,我只想說(shuō)請(qǐng)注意你的人身安全,.NET里簡(jiǎn)易實(shí)現(xiàn)IoC我這個(gè)人脾氣不太好。

開(kāi)個(gè)玩笑,對(duì)于Top也依賴(lài)于具體的事確實(shí)是有的,后面會(huì)有說(shuō)明)

B.抽象不應(yīng)該依賴(lài)于具體,具體應(yīng)該依賴(lài)于抽象

對(duì)于依賴(lài)倒置原則定義的B來(lái)說(shuō),我分兩個(gè)部分來(lái)給大家解釋一下。

第一個(gè)部分就是抽象不應(yīng)該依賴(lài)于具體, 我們還是通過(guò)代碼來(lái)說(shuō)明吧。

代碼1-3

    public interface IUnderly
    {
        void WriterLine();
        IWriter CreateWriterInstance();
    }

    public class Underly:IUnderly
    {
        public void WriterLine()
        {
            CreateWriterInstance().WriterLine();
        }
        public IWriter CreateWriterInstance()
        {
            return new Writer();
        }
    }

    public interface IWriter
    {
        void WriterLine();
    }

    public class Writer : IWriter
    {
        public void WriterLine()
        {
            Console.WriteLine("這只是一個(gè)輸出");
        }
    }

首先我們新定義了一種輸出方式Writer和它的抽象IWriter接口類(lèi)型,我們想把它應(yīng)用到Underly類(lèi)型的輸出中,然后我們修改了Underly的抽象類(lèi)型也就是在IUnderly接口類(lèi)型中新添加了一個(gè)CreateWriterInstance()方法,并且這個(gè)方法的返回類(lèi)型是Writer的抽象,這樣就對(duì)應(yīng)了依賴(lài)倒置原則定義中B條的前半句話(huà):抽象不應(yīng)該依賴(lài)于具體。

錯(cuò)誤的示范,代碼1-4

    public interface IUnderly
    {
        void WriterLine();
        Writer CreateWriterInstance();
    }

這里這樣的壞處很多后果也很?chē)?yán)重,就不去細(xì)說(shuō)了慢慢體會(huì)一下應(yīng)該會(huì)感覺(jué)得到。

從依賴(lài)倒置原則定義中B條的前半句話(huà)中來(lái)看,我們可以在碩大的.NET Framework中看一下一些抽象的定義中是否有依賴(lài)于具體的,應(yīng)該是沒(méi)有至少我是沒(méi)發(fā)現(xiàn)。

對(duì)于B條定義的后半句話(huà),也就是第二個(gè)部分:具體應(yīng)該依賴(lài)于抽象,這部分的內(nèi)容就是約束我們?cè)趯?shí)際運(yùn)用設(shè)計(jì)原則的時(shí)候會(huì)出現(xiàn)的問(wèn)題,就好比上面的Top類(lèi)型依然是依賴(lài)于具體了。

對(duì)于怎么解決這樣的一個(gè)問(wèn)題,有的朋友可能已經(jīng)想到了,對(duì)的那就是依賴(lài)注入,都說(shuō)依賴(lài)注入是依賴(lài)倒置原則的實(shí)現(xiàn)方式之一是不準(zhǔn)確的,依賴(lài)注入解決的問(wèn)題是將具體到具體的依賴(lài)轉(zhuǎn)換成具體到抽象的依賴(lài)。我是這么認(rèn)為的,純屬個(gè)人觀點(diǎn)。

(ps:這是一種治標(biāo)不治本的方法,DI把對(duì)象耦合的問(wèn)題拋到了外部,也就是這樣才導(dǎo)致了IoC的誕生,后面會(huì)有介紹。)

依賴(lài)注入

圖2

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

對(duì)于上節(jié)中的示例中對(duì)象所依賴(lài)的圖示。為了能像圖1中所示的結(jié)構(gòu)那樣以及符合依賴(lài)倒置原則的定義,我們將使用依賴(lài)注入的方式,先暫時(shí)性的解決這樣的問(wèn)題。

依賴(lài)注入有三種方式,意思都差不多都是講外部抽象的引用設(shè)置到內(nèi)部來(lái)從而實(shí)現(xiàn)注入。

這里就簡(jiǎn)單示例一下,

構(gòu)造函數(shù)注入

代碼1-5

    public class Top
    {
        private IUnderly _Underly;
        public Top(IUnderly underly)
        {
            _Underly = underly;
        }

        public void Execution()
        {
            _Underly.WriterLine();
        }
    }
    public interface IUnderly
    {
        void WriterLine();
    }
    public class Underly:IUnderly
    {
        public void WriterLine()
        {
            Console.WriteLine("這只是一個(gè)底層類(lèi)型的輸出");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Top top = new Top(new Underly());
            top.Execution();

            Console.ReadLine();
        }
    }

如代碼1-5所示那樣,在Top類(lèi)型的構(gòu)造函數(shù)中定義了下層類(lèi)型的抽象作為參數(shù),以此達(dá)到依賴(lài)注入的目的。結(jié)果如圖3。

圖3

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

屬性注入

代碼1-6

    public class Top
    {
        private IUnderly _Underly;
        public Top() { }
        public Top(IUnderly underly)
        {
            _Underly = underly;
        }

        public IUnderly Underly
        {
            get { return _Underly; }
            set { _Underly = value; }
        }

        public void Execution()
        {
            _Underly.WriterLine();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Top top = new Top();
            top.Underly = new Underly();
            top.Execution();

            Console.ReadLine();
        }
    }

通過(guò)在內(nèi)部設(shè)置屬性來(lái)獲取到底層抽象的引用,結(jié)果如圖3.

接口注入

代碼1-7

    public interface IQuote
    {
        void SetQuote(IUnderly underly);
    }

    public class Top:IQuote
    {
        private IUnderly _Underly;
        public Top() { }
        public Top(IUnderly underly)
        {
            _Underly = underly;
        }

        public IUnderly Underly
        {
            get { return _Underly; }
            set { _Underly = value; }
        }

        public void Execution()
        {
            _Underly.WriterLine();
        }

        public void SetQuote(IUnderly underly)
        {
            _Underly = underly;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Top top = new Top();
            top.SetQuote(new Underly());
            top.Execution();

            Console.ReadLine();
        }
    }

接口注入的方式原理還是一樣的,讓Top實(shí)現(xiàn)定義了設(shè)置引用方法的接口,依然是將外部的底層抽象引用設(shè)置到內(nèi)部來(lái),結(jié)果還是一樣如圖3.

這樣雖說(shuō)沒(méi)什么問(wèn)題了,但也只是局部的沒(méi)有問(wèn)題,我們看一下上面三個(gè)示例中Program類(lèi)型中的測(cè)試代碼,

圖4

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

繞了一圈依賴(lài)注入是把耦合的問(wèn)題拋到了外部,拋到了要使用Top類(lèi)型的對(duì)象中,這個(gè)問(wèn)題就很?chē)?yán)重了,我們?cè)趺唇鉀Q呢?沒(méi)關(guān)系通過(guò)IoC容器來(lái)實(shí)現(xiàn)。

自定義實(shí)現(xiàn)簡(jiǎn)易IoC

這一小節(jié)就來(lái)解決上述的問(wèn)題,Ioc又叫控制反轉(zhuǎn),控制就是執(zhí)行過(guò)程上的控制,反轉(zhuǎn)是往哪轉(zhuǎn)呢?

圖5

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

從圖5中我們可以看到,客戶(hù)端調(diào)用IoC容器,并且在IoC容器中執(zhí)行依賴(lài)注入操作,最后返回上層對(duì)象交給客戶(hù)端,所以控制反轉(zhuǎn)是由在客戶(hù)端的控制權(quán)交由IoC容器,在IoC容器中進(jìn)行依賴(lài)注入的操作后返回已達(dá)到控制權(quán)反轉(zhuǎn)的目的,從來(lái)消弱對(duì)象間的耦合程度。

那么IoC容器要做哪些工作呢?

圖6

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

核心功能:生成依賴(lài)注入過(guò)程中的上層對(duì)象

基礎(chǔ)流程:

1.需要向IoC容器中注冊(cè)依賴(lài)注入過(guò)程中抽象、具體。

2.在使用IoC的時(shí)候需向IoC中注冊(cè)上層對(duì)象的類(lèi)型。

3.解析上層對(duì)象類(lèi)型,并且執(zhí)行生成對(duì)象操作

4.返回上層對(duì)象實(shí)例

功能對(duì)象定義:

1.抽象、具體關(guān)系維護(hù)的對(duì)象,用以維護(hù)依賴(lài)注入過(guò)程中抽象、具體的對(duì)應(yīng)關(guān)系。

2.解析對(duì)象類(lèi)型的對(duì)象,根據(jù)依賴(lài)注入的幾種方式分析對(duì)象類(lèi)型的構(gòu)造和公共屬性并且生成,(公共屬性是符合IoC框架中定義的標(biāo)準(zhǔn))。

3.公共屬性標(biāo)準(zhǔn)對(duì)象,用以通知IoC框架上層對(duì)象中哪些公共屬性需要被注入。

4.執(zhí)行過(guò)程對(duì)象,用以表示框架執(zhí)行流程,框架入口點(diǎn)。

初步就這樣定了,有可能下面定義的類(lèi)型中上面沒(méi)有定義到,但是不妨礙,知道基礎(chǔ)流程就行了。那現(xiàn)在就開(kāi)始吧。

首先我們要定義IoC框架入口點(diǎn),

代碼1-8

namespace FrameWork.IoC.Achieve.IoCAbstractBasics
{
    public interface IIoCKernel
    {
        IIoCKernel Bind<T>();
        IIoCKernel To<U>() where U : class;
        V GetValue<V>() where V : class;
    }
}

對(duì)于IIoCKernel類(lèi)型的定義,Bind和To兩個(gè)方法用于綁定抽象、具體到關(guān)系維護(hù)的對(duì)象中,而GetValue()方法則是用以獲取上層對(duì)象的實(shí)例,對(duì)于這種入口點(diǎn)的使用方式我是模仿的Ninject框架,會(huì)在最后的示例中演示怎么使用。(因?yàn)槲抑挥眠^(guò)這一個(gè),還是個(gè)半吊子只是簡(jiǎn)單的用過(guò))

下面我們就來(lái)實(shí)現(xiàn)一下IIoCKernel,示例代碼1-9.

代碼1-9

using FrameWork.IoC.Achieve.IoCAbstractBasics;


namespace FrameWork.IoC.Achieve.IoCBasics
{
    public class IoCKernel : IIoCKernel
    {
        private Type _BaseType;

        public IoCKernel()
        {
            IoCContext.Context.DITyoeInfoManage = new DITypeInfoManage();
        }

        public IIoCKernel Bind<T>()
        {
            _BaseType = typeof(T);
            return this;
        }

        public IIoCKernel To<U>() where U : class
        {
            Type achieveType = typeof(U);
            if (achieveType.BaseType == _BaseType||achieveType.GetInterface(_BaseType.Name)!=null)
            {
                IoCContext.Context.DITyoeInfoManage.AddTypeInfo(_BaseType, achieveType);
            }
            return this;
        }

        public V GetValue<V>() where V : class
        {
           return IoCContext.Context.DITypeAnalyticalProvider.CreteDITypeAnalaytical().GetValue<V>();
        }
    }
}

在代碼1-9中,IoCKernel實(shí)現(xiàn)了IIoCKernel接口,首先在其構(gòu)造函數(shù)中,我們對(duì)抽象、具體關(guān)系維護(hù)的對(duì)象進(jìn)行了初始化,并且設(shè)置到了當(dāng)前IoC框架的上下文中,我們這里先停一下,看一下抽象、具體關(guān)系維護(hù)對(duì)象的構(gòu)造,示例代碼1-10.

代碼1-10

namespace FrameWork.IoC.Achieve.IoCBasics
{
    /// <summary>
    /// DI類(lèi)型關(guān)系信息管理
    /// </summary>
    public class DITypeInfoManage
    {
        private Dictionary<Type, Type> _DITypeInfo;
        public DITypeInfoManage()
        {
            _DITypeInfo = new Dictionary<Type, Type>();
        }

        /// <summary>
        /// 添加DI類(lèi)型關(guān)系
        /// </summary>
        /// <param name="key">抽象類(lèi)型</param>
        /// <param name="value">實(shí)現(xiàn)類(lèi)型</param>
        public void AddTypeInfo(Type key, Type value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (_DITypeInfo.ContainsKey(key))
            {
                return;
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            _DITypeInfo.Add(key, value);
        }

        /// <summary>
        /// 獲取DI類(lèi)型關(guān)系的實(shí)現(xiàn)類(lèi)型
        /// </summary>
        /// <param name="key">抽象類(lèi)型</param>
        /// <returns></returns>
        public Type GetTypeInfo(Type key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (_DITypeInfo.ContainsKey(key))
            {
                return _DITypeInfo[key];
            }
            return null;
        }

        public bool ContainsKey(Type key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            return _DITypeInfo.ContainsKey(key);
        }
    }
}

DITypeInfoManage類(lèi)型對(duì)象表示著抽象、具體類(lèi)型關(guān)系的信息維護(hù),實(shí)則就是在內(nèi)部封裝了鍵值隊(duì),這里就不多說(shuō)了,然后我們?cè)倏匆幌麓a1-9中IoC框架入口點(diǎn)類(lèi)型的構(gòu)造函數(shù)中初始化DITypeInfoManage類(lèi)型設(shè)置的上下文對(duì)象,來(lái)看示例代碼1-11.

using FrameWork.IoC.Achieve.IoCAbstractBasics;
using FrameWork.IoC.Achieve.Providers;
using FrameWork.IoC.Achieve.IoCBasics;

namespace FrameWork.IoC.Achieve
{
    public class IoCContext
    {
        private IoCContext() { }

        private static IoCContext _Context;

        public static IoCContext Context
        {
            get 
            {
                if (_Context == null)
                {
                    _Context = new IoCContext();
                }
                return _Context;
            }
        }

        private IDITypeAnalyticalProvider _DITypeAnalyticalProvider;

        public IDITypeAnalyticalProvider DITypeAnalyticalProvider
        {
            get
            {
                if (_DITypeAnalyticalProvider == null)
                {
                    _DITypeAnalyticalProvider = new DefualtDITypeAnalyticalProivder();
                }
                return _DITypeAnalyticalProvider;
            }
            set
            {
                _DITypeAnalyticalProvider = value;
            }
        }

        private DITypeInfoManage _DITypeInfoManage;

        public DITypeInfoManage DITyoeInfoManage
        {
            get
            {
                return _DITypeInfoManage;
            }
            set
            {
                _DITypeInfoManage = value;
            }
        }
    }
}

代碼1-11中的定義的IoCContext說(shuō)是上下文對(duì)象,說(shuō)是這么說(shuō),用以維護(hù)框架中必要的信息,實(shí)則就是一個(gè)單例模式的對(duì)象,但是意義上它還是上下文對(duì)象,在這個(gè)對(duì)象里面維護(hù)著所要依賴(lài)注入的抽象、具體類(lèi)型維護(hù)的對(duì)象,這個(gè)對(duì)象我們上面代碼1-10看過(guò)了,還有一個(gè)就是分析上層類(lèi)型的提供程序?qū)ο?,分析上層?lèi)型的提供程序?qū)ο笫怯靡陨煞治錾蠈宇?lèi)型對(duì)象的,這樣做便于對(duì)外擴(kuò)展,我們就這樣順著往下看,看一下分析上層類(lèi)型的提供程序?qū)ο?,示例代碼1-12。

代碼1-12

using FrameWork.IoC.Achieve.IoCAbstractBasics;

namespace FrameWork.IoC.Achieve.Providers
{
    public interface IDITypeAnalyticalProvider
    {
        IDITypeAnalytical CreteDITypeAnalaytical();
    }
}

這里的IDITypeAnalytical接口類(lèi)型就是分析類(lèi)型的抽象,在提供程序抽象中用以它來(lái)做返回類(lèi)型,這也遵循著依賴(lài)倒置原則B條的抽象不依賴(lài)于具體?,F(xiàn)在我們來(lái)看一下默認(rèn)實(shí)現(xiàn),示例代碼1-13.

代碼1-13

using FrameWork.IoC.Achieve.IoCAbstractBasics;
using FrameWork.IoC.Achieve.IoCBasics;


namespace FrameWork.IoC.Achieve.Providers
{
    public class DefualtDITypeAnalyticalProivder:IDITypeAnalyticalProvider
    {
        public IDITypeAnalytical CreteDITypeAnalaytical()
        {
            return new DITypeAnalytical();
        }
    }
}

在代碼1-13中定義的就是默認(rèn)的分析上層類(lèi)型提供程序了,默認(rèn)返回的就是我們框架中默認(rèn)的分析上層類(lèi)型對(duì)象,現(xiàn)在我們就來(lái)看一下分析上層類(lèi)型對(duì)象的抽象和具體實(shí)現(xiàn),示例代碼1-14。

代碼1-14

namespace FrameWork.IoC.Achieve.IoCAbstractBasics
{
    public interface IDITypeAnalytical
    {
        T GetValue<T>();
    }
}

只是定義了一個(gè)泛型的GetValue()方法,泛型類(lèi)型當(dāng)然就是所需要執(zhí)行依賴(lài)注入并且生成的上層對(duì)象類(lèi)型了,這里沒(méi)什么好說(shuō)的,直接來(lái)看分析上層類(lèi)型的具體實(shí)現(xiàn)吧,示例代碼1-15.

代碼1-15

using FrameWork.IoC.Achieve.IoCAbstractBasics;
using System.Reflection;

namespace FrameWork.IoC.Achieve.IoCBasics
{
    public class DITypeAnalytical : IDITypeAnalytical
    {

        public T GetValue<T>()
        {
            Type type = typeof(T);
            return (T)TypeAnalytical(type);
        }

        private object TypeAnalytical(Type type)
        {
            ConstructorInfo[] constructorInfos = type.GetConstructors();
            object instance = null;
            #region 構(gòu)造函數(shù)注入
            foreach (ConstructorInfo conInfo in constructorInfos)
            {
                if (conInfo.GetParameters().Length > 0)
                {
                    ParameterInfo[] paras = conInfo.GetParameters();
                    List<object> args = new List<object>();

                    foreach (ParameterInfo para in paras)
                    {
                        if (IoCContext.Context.DITyoeInfoManage.ContainsKey(para.ParameterType))
                        {
                            object par = TypeAnalytical(IoCContext.Context.DITyoeInfoManage.GetTypeInfo(para.ParameterType));
                            args.Add(par);
                        }
                    }
                    instance = CreateInstance(type, args.ToArray());
                    break;
                }
            }
            #endregion
            if (instance == null)
            {
                instance = CreateInstance(type);
            }
            #region 屬性注入
            if (type.GetProperties().Length > 0)
            {
                PropertyInfo[] proertyInfos = type.GetProperties();
                foreach (PropertyInfo propertyInfo in proertyInfos)
                {
                    if (propertyInfo.GetCustomAttributes(typeof(DITypeAttribute), false).Length > 0)
                    {
                        if (IoCContext.Context.DITyoeInfoManage.ContainsKey(propertyInfo.PropertyType))
                        {
                            object propertyvalue = TypeAnalytical(IoCContext.Context.DITyoeInfoManage.GetTypeInfo(propertyInfo.PropertyType));
                            propertyInfo.SetValue(instance, propertyvalue, null);
                        }
                    }
                }
            }
            #endregion

            return instance;
        }

        private object CreateInstance(Type type,params object[] args)
        {
            return Activator.CreateInstance(type, args);
        }
    }
}

在代碼1-15的定義中,主要的核心功能在TypeAnalytical()方法中,這里主要說(shuō)明一下這個(gè)方法的執(zhí)行過(guò)程,首先是根據(jù)方法參數(shù)傳入的類(lèi)型,這個(gè)類(lèi)型就是要實(shí)現(xiàn)依賴(lài)注入的類(lèi)型,為什么不說(shuō)這個(gè)參數(shù)類(lèi)型是上層類(lèi)型?

是因?yàn)樵谑紫葓?zhí)行的過(guò)程中傳入的是上層類(lèi)型,然后判斷其類(lèi)型的構(gòu)造函數(shù),讀取構(gòu)造函數(shù)的參數(shù)類(lèi)型根據(jù)【抽象、具體類(lèi)型的維護(hù)對(duì)象】來(lái)查找當(dāng)前上層類(lèi)型是否需要進(jìn)行構(gòu)造函數(shù)依賴(lài),如果【抽象、具體類(lèi)型的維護(hù)對(duì)象】中存在所需的類(lèi)型,則對(duì)上層類(lèi)型的構(gòu)造函數(shù)參數(shù)類(lèi)型進(jìn)行實(shí)例創(chuàng)建,并且再次調(diào)用TypeAnalytical()方法,因?yàn)槲覀儾荒艽_定上層類(lèi)型構(gòu)造函數(shù)的參數(shù)類(lèi)型是否需要進(jìn)行依賴(lài)注入,所以這里是遞歸的。

在創(chuàng)建完上層類(lèi)型構(gòu)造函數(shù)的參數(shù)類(lèi)型實(shí)例后,便會(huì)對(duì)上層類(lèi)型進(jìn)行實(shí)例創(chuàng)建,因?yàn)檫@是依賴(lài)注入中構(gòu)造函數(shù)注入的一種方式。

在此完畢后判斷TypeAnalytical()方法中instance實(shí)例是否為空,如果是空的則說(shuō)明上層類(lèi)型沒(méi)有采取構(gòu)造函數(shù)注入的方式,在此我們還是要?jiǎng)?chuàng)建它的實(shí)例,以便下面的進(jìn)行屬性注入時(shí)對(duì)實(shí)例屬性的賦值。

之后我們會(huì)對(duì)上層類(lèi)型的所有公共屬性根據(jù)條件進(jìn)行查找,查找符合我們定義標(biāo)準(zhǔn)的公共屬性,也就是DITypeAttribute類(lèi)型,這個(gè)類(lèi)型下面會(huì)貼出示例代碼,假使在找到需要依賴(lài)注入的公共屬性后執(zhí)行過(guò)程便和上面執(zhí)行構(gòu)造函數(shù)注入的方式相同。

(ps:這里功能的定義并不是很?chē)?yán)謹(jǐn),而且只針對(duì)了構(gòu)造函數(shù)注入和屬性注入兩種方式,并沒(méi)有對(duì)接口注入提供支持。)

下面我們看一下上面所說(shuō)的屬性注入的特性類(lèi)定義(也就是框架定義的規(guī)范),示例代碼1-16.

代碼1-16

namespace FrameWork.IoC.Achieve.IoCBasics
{
    [AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)]
    public class DITypeAttribute:Attribute
    {
        public DITypeAttribute() { }
    }
}

就是一個(gè)簡(jiǎn)單的特性類(lèi)定義,用作規(guī)范約束。

最后我們看一下測(cè)試用例:

代碼1-17

using FrameWork.IoC.Achieve.IoCBasics;
using FrameWork.IoC.Achieve.IoCAbstractBasics;

using FrameWork.IoC.Case;
using FrameWork.IoC.Case.Test.TestOne;
using FrameWork.IoC.Case.Test.TestTwo;

namespace FrameWork.IoC.Case.Test
{
    public class DITest
    {
        private IAbstractOne _AbstractOne;
        public DITest(IAbstractOne abstractone)
        {
            _AbstractOne = abstractone;
        }

        private IAbstractTwo _AbstractTwo;

        [DIType]
        public IAbstractTwo AbstractTwo
        {
            get
            {
                return _AbstractTwo;
            }
            set
            {
                _AbstractTwo = value;
            }
        }

        public void Writer(string meg)
        {
            _AbstractOne.WriterLine(meg);
            _AbstractTwo.WriterLine(meg);
        }
    }
}

代碼1-17定義中對(duì)DITest分別進(jìn)行了構(gòu)造函數(shù)、屬性注入,注入類(lèi)型分別對(duì)應(yīng)著IAbstractOne、IAbstractTwo。我們先來(lái)看一下IAbstractOne抽象、具體的定義,示例代碼1-18

代碼1-18

namespace FrameWork.IoC.Case.Test.TestOne
{
    public interface IAbstractOne
    {
        void WriterLine(string meg);
    }

    public class AchieveOne:IAbstractOne
    {
        private IAbstractOne_One _AbstractOne_One;
        public AchieveOne(IAbstractOne_One abstractone)
        {
            _AbstractOne_One = abstractone;
        }


        private IAbstractOne_Two _AbstractOne_Two;

        [DIType]
        public IAbstractOne_Two AbstractOne_Two
        {
            get
            {
                return _AbstractOne_Two;
            }
            set
            {
                _AbstractOne_Two = value;
            }
        }

        public void WriterLine(string meg)
        {
            _AbstractOne_One.WirterLine(meg);
            _AbstractOne_Two.WriterLine(meg);
            Console.WriteLine(meg + "-This is TestOne");
        }
    }

}

代碼1-18中定義了IAbstractOne抽象、AchieveOne具體實(shí)現(xiàn),并且在AchieveOne具體實(shí)現(xiàn)中還對(duì)IAbstractOne_One、IAbstractOne_Two分別進(jìn)行了構(gòu)造函數(shù)、屬性注入。從最上層來(lái)看就是嵌套的注入,這樣更能體現(xiàn)出IoC框架的重要性。

我們看一下IAbstractOne_One、IAbstractOne_Two類(lèi)型的抽象、具體定義,示例代碼1-19.

代碼1-19

namespace FrameWork.IoC.Case.Test.TestOne
{
    public interface IAbstractOne_One
    {
        void WirterLine(string meg);
    }

    public class AbstractOne_One:IAbstractOne_One
    {
        public void WirterLine(string meg)
        {
            Console.WriteLine(meg + "-This is TestOne_One");
        }
    }

    public interface IAbstractOne_Two
    {
        void WriterLine(string meg);
    }

    public class AbstractOne_Two:IAbstractOne_Two
    {
        public void WriterLine(string meg)
        {
            Console.WriteLine(meg + "-This is TestOne_Two");
        }
    }

}

最后我們?cè)倏匆幌翴AbstractTwo抽象和具體實(shí)現(xiàn)的定義,示例代碼1-20.

代碼1-20

namespace FrameWork.IoC.Case.Test.TestTwo
{
    public interface IAbstractTwo
    {
        void WriterLine(string meg);
    }

    public class AchieveTwo:IAbstractTwo
    {
        public void WriterLine(string meg)
        {
            Console.WriteLine(meg + "-This is TestTwo");
        }
    }

}

真的是最后我們看一下客戶(hù)端的調(diào)用代碼,示例代碼1-21,

代碼1-21

using FrameWork.IoC.Achieve.IoCBasics;
using FrameWork.IoC.Achieve.IoCAbstractBasics;

using FrameWork.IoC.Case;
using FrameWork.IoC.Case.Test;
using FrameWork.IoC.Case.Test.TestOne;
using FrameWork.IoC.Case.Test.TestTwo;

namespace FrameWork.IoC.Case
{
    class Program
    {
        static void Main(string[] args)
        {
            #region IoCTest
            IIoCKernel iocKernel = new IoCKernel();
            iocKernel.Bind<IAbstractOne>().To<AchieveOne>();
            iocKernel.Bind<IAbstractTwo>().To<AchieveTwo>();
            iocKernel.Bind<IAbstractOne_One>().To<AbstractOne_One>();
            iocKernel.Bind<IAbstractOne_Two>().To<AbstractOne_Two>();
            DITest diType = iocKernel.GetValue<DITest>();
            diType.Writer("IoCFrameWorkTest");
            #endregion
            Console.ReadLine();
        }
    }
}

最后看一下結(jié)果,如圖7

圖7

.NET里簡(jiǎn)易實(shí)現(xiàn)IoC

到這里本篇的內(nèi)容就結(jié)束了,自定義IoC只是一個(gè)參考,并沒(méi)有對(duì)IoC框架進(jìn)行深入的實(shí)現(xiàn),只是以此做一個(gè)引導(dǎo),建議大家還是選擇一款合適的IoC框架當(dāng)作學(xué)習(xí)的對(duì)象,當(dāng)然感興趣的朋友還是可以自己寫(xiě)的。

搬磚不易,且搬且用心,感謝各位工友的支持,謝謝大家。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。

網(wǎng)頁(yè)名稱(chēng):.NET里簡(jiǎn)易實(shí)現(xiàn)IoC-創(chuàng)新互聯(lián)
新聞來(lái)源:http://aaarwkj.com/article14/jcede.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站微信公眾號(hào)、靜態(tài)網(wǎng)站定制開(kāi)發(fā)、搜索引擎優(yōu)化、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
久久亚洲欧美国产精品观看| 成人性生交大片免费看多人| 日韩精品一区二区三区四区蜜桃| 天天操夜夜操狠狠操91| 国产欧美日韩午夜激情| 98热这里只有精品视频| 国产精品夜色一区二区三区不卡 | 色综合久久天天射天天干| 日本中文字幕免费专区| 国产精品伦一区二区三级| 亚洲av永久国产剧情| 精品人妻一区二区三区在线av| 国产三级系列在线观看| 五月婷婷丁香花综合网| 五月婷婷综合中文字幕在线| 蜜臀av一区二区三区人妻| 日韩中文字幕在线乱码| 亚洲男女内射在线视频| 亚洲一区日韩精品颜射 | 蜜臀一区二区三区精品免费| 成人免费av在线网址| 免费黄色福利网址大片| 欧美精品福利一区二区| 欧美日本一区二区四区| 女人天堂网av免费看| 欧美国产综合欧美一区二区三区 | 国产精品毛片在线看不卡| 免费97久久人妻一区精品| 中文字幕熟妇人妻av在线| 亚洲精品色在线网站国产呦| 有码国内精品人妻少妇| 日韩久久精品五月综合| 黄色亚洲日本欧美在线观看| 美女高潮呻吟免费观看久久久| 久久精品性少妇一区=区三区| 色综合婷婷九月中文字幕| 中文字幕av日韩在线| 国产一级无码免费视频| 成人性生交大片免费看多人| 男女爱爱视频网站久久精选| 天堂av好男人亚洲精品|