zoukankan      html  css  js  c++  java
  • 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
     
     
  • 相关阅读:
    unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type.
    Go的学习笔记之Channel发送和接收
    聊聊 PC 端自动化最佳方案
    一文彻底搞懂快速幂(原理实现、矩阵快速幂)
    一次core.<number> 文件占满磁盘空间的处理过程
    博文目录
    备忘录:C#获取微信小程序的云数据库中数据
    T-SQL——关于跨库连接查询
    .NET异步程序设计——给线程传递数据
    自研 Pulsar Starter:winfun-pulsar-spring-boot-starter
  • 原文地址:https://www.cnblogs.com/aspnetdream/p/3052599.html
Copyright © 2011-2022 走看看