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();

            

        }

运行结果:

ASP.NET MVC经典项目ProDinner项目解析(4)

再玩得复杂点,修改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("调用接口");

        }

    }

运行结果:

ASP.NET MVC经典项目ProDinner项目解析(4)

最后附有实例的源代码,可以运行一下试试看,我想看懂了这个实例的同学应该发现他的神奇之处了,我没有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
 
 

你可能感兴趣的:(asp.net)