.net framework 的控制反转和依赖注入

我们有一个类A,一个类B,A中的方法需要调用B中的方法,我们称为A依赖于B,常见的写法如下:

    public class A
    {
        private B _b;

        public A() {
            _b = new B();
        }
        public string MethodA()
        {
            return _b.MethodB();
        }
    }

    public class B
    {
        public string MethodB()
        {
            return "Do MethodB";
        }
    }

调用A中的方法

    internal class Program
    {
        static void Main(string[] args)
        {
            A _a = new A();
            Console.WriteLine(_a.MethodA());
        }
    }

 

根据依赖倒置原则,A作为高级模块,应该不依赖与B这个低级模块

依赖倒置原则

  1.高级模块不应该依赖于低级模块,两者都应该依赖抽象;

  2.抽象不应该依赖于细节,细节应该依赖于抽象。

 

因此我们加入B的抽象类,修改为

    public class A
    {
        public string MethodA(IB b)
        {
            return b.MethodB();
        }
    }

    public interface IB
    {
        string MethodB();
    }

    public class B : IB
    {
        public string MethodB()
        {
            return "Do MethodB";
        }
    }

 

这样编译时A依赖于抽象的IB,但是调用A的方法时,还需要先准备好B的实例。

        static void Main(string[] args)
        {
            A _a = new A();
            B _b = new B();
            Console.WriteLine(_a.MethodA(_b));
        }

 

因为在面向对象编程中,执行代码需要先实例化对象,再调用方法。

这里引入了一个新概念,控制反转

控制反转

  有一个独立的框架,它可以获得接口IB合适的实现类B,并主动创建这个类的实例,再赋值给A的一个字段_b,也就是说A中不需要去主动创建B相关的实例,只需要声明,B的实例由这个外部框架来负责创建并提供给A。

修改A

public class A
    {
        private IB _b;

        public A(IB b)
        {
            _b = b;
        }
        public string MethodA()
        {
            return _b.MethodB();
        }
    }

 

调用方式

        static void Main(string[] args)
        {
            IB _b = new B();
            A _a = new A(_b); 
            Console.WriteLine(_a.MethodA());
        }

 

首先 A不再依赖于B,而是依赖于抽象,然后调用A的时候,也不再需要B的实例,而是抽象接口IB的实现对象。

 

控制反转是一种设计原则,可以用来减少代码的耦合度。而依赖注入是它的一种实现方式。

 

posted @ 2023-03-01 16:12  luytest  阅读(126)  评论(0编辑  收藏  举报