对于依赖注入的初步理解

1.产生背景: 面向对象原则之一——开放封闭原则(OCP)的要求,即 一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的,即将变化隔离,使得变化部分发生变化时,不变部分不受影响。 为了做到这一点,要利用面向对象中的多态性,使用多态性后,客户类不再直接依赖服务类,而是依赖于一个抽象的接口,这样,客户类就不能在内部直接实例化具体的服务类。但是,客户类在运作中又客观需要具体的服务类提供服务,因为接口是不能实例化去提供服务的。就产生了“客户类不准实例化具体服务类”和“客户类需要具体服务类”这样一对矛盾。为了解决这个矛盾,开发人员提出了一种模式:客户类定义一个注入点,用于服务类的注入,而客户类的客户类负责根据情况,实例化服务类,注入到客户类中,从而解决了这个矛盾。
(客户类要使用具体的服务类,但是根据面向对象的原则客户类中不能实例化具体服务类,因此需要在客户端定义一种注入的方法,使之无需实例化即可调用具体服务类)

传统方法:客户类中实例化具体的服务类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Origin
{
    class Program
    {
        static void Main(string[] args)
        {
            Novel novel = new Novel();
            novel.ByReading();
        }
    }

    class Read
    {
        public void ToRead()
        {
            var tempBook = new Novel(); //问题所在——客户类实例化具体的服务类
            tempBook.ByReading();
        }
    }

    abstract class Book
    {
        public abstract void ByReading();
    }

    class Novel : Book
    {
        public override void ByReading()
        {
            Console.WriteLine("Novel");
        }
    }
}

2.定义: 依赖注入(Dependency Injection),是这样一个过程:由于某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点。在程序运行过程中,客户类不直接实例化具体服务类实例,而是客户类的运行上下文环境或专门组件负责实例化服务类,然后将其注入到客户类中,保证客户类的正常运行。

3.目的:解耦,降低耦合度

4.依赖注入实现方式:

(1) 构造函数注入:具体服务类在客户类之外已经实例化完毕,再具体服务类的实例当作参数传入客户类的构造函数中,从而实现注入
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConstructorInjection
{
    class Program
    {
        static void Main(string[] args)
        {
            Novel novel = new Novel();
            Magazine magazine = new Magazine();

            Read readNovel = new Read(novel);
            Read readMagazine = new Read(magazine);

            readNovel.ToRead();
            readMagazine.ToRead();
        }
    }

    class Read
    {
        private Book book;

        public Read(Book _book)
        {
            this.book = _book;
        }

        public void ToRead()
        {
            book.ByReading();
        }
    }

    abstract class Book
    {
        public abstract void ByReading();
    }

    class Novel : Book
    {
        public override void ByReading()
        {
            Console.WriteLine("You are reading Novel");
        }
    }

    class Magazine : Book
    {
        public override void ByReading()
        {
            Console.WriteLine("You are reading Magazine");
        }
    }
}

(2) getter & setter注入:在客户类中使用get和set注入具体服务类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SetterInjection
{
    class Program
    {
        static void Main(string[] args)
        {
            Read read = new Read();

            read.Book = new Novel();
            read.ToRead();

            read.Book = new Magazine();
            read.ToRead();
        }
    }

    class Read
    {
        private Book book;

        public Book Book
        {
            get{ return book; }
            set{ book = value; }
        }

        public void ToRead()
        {
            book.ByReading();
        }
    }

    abstract class Book
    {
        public abstract void ByReading();
    }

    class Novel : Book
    {
        public override void ByReading()
        {
            Console.WriteLine("You are reading Novel");
        }
    }

    class Magazine : Book
    {
        public override void ByReading()
        {
            Console.WriteLine("You are reading Magazine");
        }
    }
}

(3)接口注入:运用接口在客户类中实现注入具体服务类的函数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterfaceInjection
{
    class Program
    {
        static void Main(string[] args)
        {
            IBook novel = new Novel();
            IBook magazine = new Magazine();

            Read read = new Read();

            read.Inject(novel);
            read.ToRead();

            read.Inject(magazine);
            read.ToRead();
        }
    }

    
    interface IRead
    {
        void Inject(IBook book);
    }
    

    class Read : IRead
    {
        IBook book;

        public void Inject(IBook _book)
        {
            book = _book;
        }

        public void ToRead()
        {
            book.ByReading();
        }
    }


    interface IBook
    {
        void ByReading();
    }

    class Novel : IBook
    {
        public void ByReading()
        {
            Console.WriteLine("You are reading Novel");
        }
    }

    class Magazine : IBook
    {
        public void ByReading()
        {
            Console.WriteLine("You are reading Magazine");
        }
    }
}

参考资料:https://www.codeproject.com/Tips/657668/Dependency-Injection-DI
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值