控制反转(IOC)、依赖注入(DI)

一、概念

1.控制反转(IOC):通俗理解为“将控制权交出去,交给调用你的人去控制”,是一种设计思想或原则,而不是一种具体的实现。

具体实现控制反转最常见是方法是依赖注入。

2.依赖注入(DI):通俗理解为“自己调用方法前,先将它依赖传递给它,再进行调用”

二、举例:

A类中需要调用B类中的b方法,但是b方法中又需要C类中的c方法。

1.未使用控制反转思想:

A类调用B类,B类直接调用C类。

namespace test
{
    public class A
    {
        public int a()
        {
            B bb = new B();
            return bb.b();
        }
    }

    public class B
    {
        public int b()
        {
            int op = 1;
            op++;

            //b方法依赖C中c方法
            C cc = new C();
            op = op * cc.c();
            return op;
        }
    }

    public class C
    {
        public int c()
        {
            //ToDo
            return 2;
        }
    }
}

2.使用依赖注入实现控制反转思想:

A类调用B类时,首先将C类对象传递给B类, B类再调用C类。

namespace test
{
    public class A
    {
        public int a()
        {
            B bb = new B(new C());
            return bb.b();
        }
    }

    public class B
    {
        private C _cc;
        //构造函数注入
        public B(C cc) {
            _cc = cc;
        }

        public int b()
        {
            int op = 1;
            op++;

            //b方法依赖C中c方法,通过B中构造函数,将C注入
            op = op * _cc.c();
            return op;
        }
    }

    public class C
    {
        public int c()
        {
            //ToDo
            return 2;
        }
    }
}

三、利用依赖注入实现控制反转的优点

优点:当依赖项需要修改时,使用依赖注入就可以尽可能改动最小(解耦,耦合度降低)

说明:当构造函数中参数过多时,也不好维护。但是,但是,这时候我们就可以利用IOC容器自行维护,容器常见的有Castle Windsor,Unity,Ninject,StructureMap和Autofac等。

四、依赖注入方式

1.构造函数注入:已经在 “二、举例 > 2.使用依赖注入实现控制反转思想” 示例了
namespace test
{
    public class A
    {
        public int a()
        {
            B bb = new B(2);
            return  bb.b();
        }
    }

    public class B
    {
        private int _num;

        //构造函数注入
        public B(int num) {
            _num = num;
        }

        public int b()
        {
            return (new Random()).Next(1, 9) * _num;
        }
    }
    
}

2.属性注入
namespace test
{
    public class A
    {
        public int a()
        {
            B bb = new B();
            bb.num = 3;
            return bb.b();
        }
    }

    public class B
    {
        public int num;

        //属性注入

        public int b()
        {
            return (new Random()).Next(1, 9) * num;
        }
    }

}
posted @ 2019-11-08 17:14  预立科技  阅读(55)  评论(0)    收藏  举报