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是个很好的开源项目,有时间可以看看源代码,这节内容比较多,我附上我的源代码,可以再继续讨论。

本节源代码:https://files.cnblogs.com/aspnetdream/ConsoleApplication2.rar
 
 
posted @   aspnetdream  阅读(2240)  评论(5编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示