ASP.NET MVC經典項目ProDinner項目解析(4)


四、Infra層解析

ProDinner使用了Castle.Windsor開源項目,最直接最根本的使用了依賴倒轉,說得通俗點,我們在使用接口的時候,往往可以實現,實現層的多樣化,基於實現接口的多樣化,我們有不同的調用方式,但是在調用接口的時候,我們最終需要選擇那樣實現來運行代碼,例如:

    public interface IA
    {
        void Print();
    }

    public class AA : IA
    {
        public void Print()
        {
            Console.Write("AA實現");
        }
    }

    public class BB : IA
    {
        public void Print()
        {
            Console.Write("BB實現" + "_BB");
        }
    }

無論哪種實現,我們在使用IA接口的時候,最終需要給接口實例化一個對象,要么是AA,要么是BB。這就是C#基本的多態。在面對復雜的項目層次划分的時候,如果我們有多種實現,或者這種實現會不停的變更時候,其實我們依然擺脫不了修改代碼的噩運。Castle.Windsor實現了依賴倒轉,通過配置來告訴程序當前是誰來實現接口,所以我們在Core、Data層沒有看見任何具體的實例邏輯代碼。順便帶一句Caslte是個開源項目,據我所知ASP.NET MVC很大程度上借鑒了該開源項目。另外博客園李會軍前輩的博客有介紹這方面的文章。

官網:http://www.castleproject.org

究竟如何是實現這種高抽象化的接口配置呢,看看實例吧

首先定義2個接口

    public interface IA
    {
        void Print();
    }

    public interface IB
    {
        void Set(string str);
    }

然后分別實現這2個接口

    public class AA : IA
    {
        public void Print()
        {
            Console.Write("AA實現");
        }
    }

    public class BB : IB
    {
        public void Set(string str)
        {
            Console.Write(str + "_BB的實現");
        }
    }

調用實現代碼:

        static void Main(string[] args)
        {
            IWindsorContainer wcs = new WindsorContainer(new Castle.Windsor.Configuration.Interpreters.XmlInterpreter("http://www.cnblogs.com/XMLFile.xml"));

            wcs.AddComponent("mykey", typeof(IA), typeof(AA));
            wcs.AddComponent("format", typeof(IB), typeof(BB));

            IA log = (IA)wcs["mykey"];
            log.Print();
            
        }

運行結果:

再玩得復雜點,修改AA類實現代碼如下:

    public class AA : IA
    {
        IB _ib;
        public AA(IB ib)
        {
            _ib = ib;
        }
        public void Print()
        {
            Print(_ib);
        }

        public void Print(IB ib)
        {
            Console.Write("AA實現");
            ib.Set("調用接口");
        }
    }

運行結果:

最后附有實例的源代碼,可以運行一下試試看,我想看懂了這個實例的同學應該發現他的神奇之處了,我沒有New任何一個對象,實現了,對AA和BB具體實現的調用,也就是說代碼居然是接口調接口,實現了具體操作。

回到我們這里需要講解的ProDinner,Infra層其實就是運用了Castle的這種特定的方式實現了依賴倒轉。

    public static class IoC
    {
        private static readonly object LockObj = new object();

        private static IWindsorContainer container = new WindsorContainer();

        public static IWindsorContainer Container
        {
            get { return container; }

            set
            {
                lock (LockObj)
                {
                    container = value;
                }
            }
        }

        public static T Resolve<T>()
        {
            return container.Resolve<T>();
        }

        public static object Resolve(Type type)
        {
            return container.Resolve(type);
        }
    }

全篇代碼並不復雜,但為后續的依賴倒轉提供了幾個基礎的接口實現,其實吧這要說C#有T這么個好東西哇。

private static IWindsorContainer container = new WindsorContainer();聲明一個唯一的依賴倒轉容器
Container屬性通過加鎖的方式保證這個容器的唯一性,就如同我們Entity Framework框架中DbContext一樣保證唯一
Resolve就是為實現不同的類型容器而實現的接口。

這層為實現抽象層和后續的業務實現層建立了橋梁,Castle是個很好的開源項目,有時間可以看看源代碼,這節內容比較多,我附上我的源代碼,可以再繼續討論。

本節源代碼:http://files.cnblogs.com/aspnetdream/ConsoleApplication2.rar
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM