C#开发环境下针对依赖注入和IOC的理解

前段时间在网上看到许多跟依赖注入相关的文章,总的来说我觉得比较有道理的一句话那就是:在依赖倒置原则中,咱们在依赖的时候不应该依赖具体实现,而是要依赖抽象。本篇文章作者将以三层架构为背景从依赖注入到IOC,一步步开始讲起。

首先咱们来看依赖注入的代码:

数据访问层:

这里首先我建了一个设备接口,里面有设备读写方法

  public interface IDeviceHandle
    {
        void Wirte();
        void Read();
    }
  public class MitsubishiPLC : IDeviceHandle
    {
        public  void Read()
        {
            Console.WriteLine("这是三菱设备的数据读取");
        }

        public  void Wirte()
        {
            Console.WriteLine("这是三菱设备的数据写入");
        }
    }


 public  class OmronPLC: IDeviceHandle
    {
        public  void Read()
        {
            Console.WriteLine("这是欧姆龙设备的数据读取");
        }

        public  void Wirte()
        {
            Console.WriteLine("这是欧姆龙设备的数据写入");
        }
    }

 public  class SiemensPLC: IDeviceHandle
    {
        public  void Read()
        {
            Console.WriteLine("这是西门子设备的数据读取");
        }

        public  void Wirte()
        {
            Console.WriteLine("这是西门子设备的数据写入");
        }
    }

根据不同设备类来继承同一个接口,根据设备自身实现不同的读写方法。这也便于以后有新的设备则创建一个新的设备对象。

业务层:

 public class Business
    {

        IDeviceHandle deviceHandle;
        public Business(IDeviceHandle deviceHandle)
        {
            this.deviceHandle = deviceHandle;
        }

        public void Write()
        {
            deviceHandle.Wirte();
        }
        public void Read()
        {
            deviceHandle.Read();
        }


    }

业务层这里只用了抽象接口,而没有具体实现那个设备的对象的声明,真正的对象声明放在了业务类的构造函数中,这也是依赖注入中的构造注入

视图层:

   static void Main(string[] args)
        {
            DITest();          
            Console.ReadKey();

        }

   public static void DITest()
        {
            Business business = new Business(new OmronPLC());
            business.Write();
        }

这样依赖注入的好处是,假如以后新增一个其他的设备对象,我只需要在数据访问层新增后,不会破坏其他设备内部具体实现,属于可以扩展,禁止修改,业务层也不需要修改,业务层只需要传入具体使用对象即可,降低各个层之间的耦合。但是我发现应用层在传入具体对象的时候需要实例化某个对象,这就产生了视图层对于数据访问层的依赖,而在三层架构中应该是禁止视图层对数据访问层产生依赖。使用IOC 容器(控制反转)就可以解决这个问题

IOC容器 视图层

static void Main(string[] args)
        {
            IOCTest();          
            Console.ReadKey();

        }

   public static void IOCTest()
        {
            ContainerBuilder containerBuilder = new ContainerBuilder();
            var xxx = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "DAL.dll");
            List vs = new List();
            XMLHelp xMLHelp = new XMLHelp();
            vs = xMLHelp.ReadNodeData();
            foreach (string str in vs)
            {
                containerBuilder.RegisterAssemblyTypes(xxx).Where(x => x.Name == str).Named(str).AsImplementedInterfaces(); //注册的时候声明名字,方便实例指定
            }
            IContainer container = containerBuilder.Build();//获取关系存放在集合中
            if (container.IsRegisteredWithName("OmronPLC")) //查询是否已经注册
            {
                IDeviceHandle deviceHandle = container.ResolveNamed("OmronPLC");// 假如已经注册则执行
                deviceHandle.Wirte();
            }
        }

这里我使用的是AutoFac IOC容器,具体怎么使用这里就不详细说明了,具体还是聊聊对于架构的理解,这里IOC容器的作用就是把原本对业务层的依赖注入转到IOC容器中,而IOC会把数据访问层的对象一一注册,我在这里的话是通过外部文件实现多个注册(一个个注册太麻烦了,假如上百个对象那就要敲上百个注册),再根据视图层传入对象名字去实例化指定对象(其实可以全部根据外部文件去做需求订制),这样视图层不需要依赖到数据访问层,符合三层架构的设计规则,也就是说视图层目前只依赖IOC容器,这样耦合也大幅度降低。

你可能感兴趣的:(c#)