实验十二 依赖注入的应用

合集下载

什么是依赖注入

什么是依赖注入

什么是依赖注⼊1 定义依赖注⼊(Dependency Injection),简称DI,类之间的依赖关系由容器来负责。

简单来讲a依赖b,但a不创建(或销毁)b,仅使⽤b,b的创建(或销毁)交给容器。

2 例⼦为了把DI讲清楚,我们需要举⼀个简单例⼦。

例⼦⾜够⼩,希望让你能直观的了解DI⽽不会陷⼊真实⽰例的泥潭。

例⼦:⼩明要杀怪,那⼩明拿什么武器杀怪呢?可以⽤⼑、也可以⽤拳头、斧⼦等。

⾸先,我们创建⼀个演员类,名字叫“⼩明”,具有杀怪功能。

namespace NoInjection.ConsoleApp{public class Actor{private string name = "⼩明";public void Kill(){var knife = new Knife();knife.Kill(name);}}}然后,我们再创建⼀个武器-⼑类,具有杀怪功能。

using System;namespace NoInjection.ConsoleApp{public class Knife{public void Kill(string name){Console.WriteLine($"{name}⽤⼑杀怪");}}}最后,我们客户端调⽤演员类,执⾏杀怪功能。

using System;namespace NoInjection.ConsoleApp{class Program{static void Main(string[] args){var actor = new Actor();actor.Kill();Console.ReadKey();}}}让我们来看看输出结果:⼩明⽤⼑杀怪通过这个例⼦我们可以看到,Actor类依赖Knife类,在Actor中创建Knife,执⾏Knife.Kill⽅法。

我们可以回顾⼀下DI的定义,a依赖b,但a不创建(或销毁)b,仅使⽤b,显然这个不符合DI做法。

IoC模式(依赖、依赖倒置、依赖注入、控制反转)

IoC模式(依赖、依赖倒置、依赖注入、控制反转)

IoC模式(依赖、依赖倒置、依赖注⼊、控制反转)1.依赖依赖就是有联系,有地⽅使⽤到它就是有依赖它,⼀个系统不可能完全避免依赖。

如果你的⼀个类或者模块在项⽬中没有⽤到它,恭喜你,可以从项⽬中剔除它或者排除它了,因为没有⼀个地⽅会依赖它。

下⾯看⼀个简单的⽰例:/// <summary>///⽤户播放媒体⽂件/// </summary>public class OperationMain{public void PlayMedia(){MediaFile _mtype = new MediaFile();Player _player = new Player();_player.Play(_mtype);}}/// <summary>///播放器/// </summary>public class Player{public void Play(MediaFile file){Console.WriteLine(file.FilePath);}}/// <summary>///媒体⽂件/// </summary>public class MediaFile{public string FilePath { get; set; }}上⾯是⼀个⽤户⽤播放器播放⽂件简单⽰例,⽤户操作是OperationMain类中的PlayMedia⽅法,打开⼀个播放器,选择⼀个⽂件来播放。

先看看他们之间的依赖关系,可以简单找到有3个依赖1. Player依赖MediaFile2. OperationMain依赖Player3. OperationMain依赖MediaFile2.依赖倒置需求增加了,要⽤不同的播放器,播放不同的⽂件,我们要抽象出来,减少耦合。

耦合关系就是依赖关系,如果依赖关系相当繁杂,牵⼀发⽽动全⾝,很难维护;依赖关系越少,耦合关系就越低,系统就越稳定,所以我们要减少依赖。

ASP.NETCore中的依赖注入(2):依赖注入(DI)

ASP.NETCore中的依赖注入(2):依赖注入(DI)

Core中的依赖注⼊(2):依赖注⼊(DI)IoC主要体现了这样⼀种设计思想:通过将⼀组通⽤流程的控制从应⽤转移到框架之中以实现对流程的复⽤,同时采⽤“好莱坞原则”是应⽤程序以被动的⽅式实现对流程的定制。

我们可以采⽤若⼲设计模式以不同的⽅式实现IoC,⽐如我们在介绍的模板⽅法、⼯⼚⽅法和抽象⼯⼚,接下来我们介绍⼀种更为有价值的IoC模式,即依赖注⼊(DI:Dependency Injection,以下简称DI)。

⽬录⼀、由外部容器提供服务对象⼆、三种依赖注⼊⽅式构造器注⼊属性注⼊⽅法注⼊三、实例演⽰:创建⼀个简易版的DI框架⼀、由外部容器提供服务对象和上⾯介绍的⼯⼚⽅法和抽象⼯⼚模式⼀样,DI旨在实现针对服务对象的动态提供。

具体来说,服务的消费者利⽤⼀个独⽴的容器(Container)来获取所需的服务对象,容器⾃⾝在提供服务对象的过程中会⾃动完成依赖的解析与注⼊。

话句话说,由DI容器提供的这个服务对象是⼀个” 开箱即⽤”的对象,这个对象⾃⾝直接或者间接依赖的对象已经在初始化的⼯程中被⾃动注⼊其中了。

举个简单的例⼦,我们创建⼀个名为Cat的DI容器类,那么我们可以通过调⽤具有如下定义的扩展⽅法GetService<T>从某个Cat对象获取指定类型的服务对象。

我之所以将其命名为Cat,源于我们⼤家都⾮常熟悉的⼀个卡通形象“机器猫(哆啦A梦)”。

它的那个四次元⼝袋就是⼀个理想的DI容器,⼤熊只需要告诉哆啦A梦相应的需求,它就能从这个⼝袋中得到相应的法宝。

DI容器亦是如此,服务消费者只需要告诉容器所需服务的类型(⼀般是⼀个服务接⼝或者抽象服务类),就能得到与之匹配的服务对象。

1:public static class CatExtensions2: {3:public static T GetService<T>(this Cat cat);4: }对于我们在演⽰的MVC框架,我们在前⾯分别采⽤不同的设计模式对框架的核⼼类型MvcEngine进⾏了改造,现在我们采⽤DI的⽅式并利⽤上述的这个Cat容器按照如下的⽅式对其进⾏重新实现,我们会发现MvcEngine变得异常简洁⽽清晰。

依赖注入例子

依赖注入例子

依赖注入例子《依赖注入:如同给代码找个贴心小助手》在编程的世界里,依赖注入听起来像是个有点高大上、让人摸不着头脑的概念,但只要理解了,就像发现了一个超级实用的小秘密。

我想跟你分享一下我所理解的依赖注入,就用一些特别接地气的例子来说吧。

想象一下,你是一个厨师,要做一道超美味的番茄炒蛋。

以前呢,你可能得自己种菜、养鸡下蛋,这多麻烦啊。

依赖注入就像是有个神奇的食材供应商。

这个供应商直接把新鲜的番茄和鸡蛋送过来给你,你只需要专注于做菜这个核心任务就行,也就是在代码里专注于实现烹饪番茄炒蛋(处理业务逻辑)的过程,而不用操心食材的来源(类内部对象的创建和管理)。

比如说,我在写一个游戏角色的代码。

游戏角色需要一个武器来战斗,要是没有依赖注入,这个角色类可能就会自己创建武器的实例。

这就好比游戏角色既要忙着自己在游戏场景里跑来跑去做任务,还得抽空去打铁造剑,是不是有点滑稽又不合理?而通过依赖注入呢,就像游戏设定专门有个武器库,游戏角色在创建的时候,可以从这个武器库“注入”适合自己的武器,这样角色类就简单多了,只需要知道怎么使用武器战斗,而不用纠结武器是怎么来的。

从开发的角度看,这简直就是让生活轻松了好多。

就好比你是个快递员(程序员),每天要送很多包裹。

没有依赖注入的时候,你还得自己生产包裹,包装包裹,标记包裹,累得半死。

一旦有了依赖注入,就突然出现了一个包裹专门处理中心,把所有包裹处理好,直接塞给你(注入到你的快递派送系统),你只要一门心思把包裹准确送到客户手里面就可以了。

而且依赖注入还让代码的维护和测试变得更容易。

还继续拿厨师的例子来说吧,如果有一天你想把鸡蛋换成鸭蛋,因为健康食材流行新趋势是鸭蛋更养生。

要是自己种菜养鸡那一套模式,你得先去搞定鸭舍和养鸭的事。

而有了依赖注入这个食材供应商,你只需要跟供应商说一声,下次送鸭蛋来就行。

在代码里就是,如果要改变依赖类的实现(把鸡蛋供应换成鸭蛋供应),只需要在依赖注入的配置那里改改就好,不需要在大量的代码里到处找创建鸡蛋实例的地方去修改。

实现依赖注入的三种方式

实现依赖注入的三种方式

实现依赖注⼊的三种⽅式依赖注⼊(DI)控制反转(IoC)⼀种重要的⽅式,就是将依赖对象的创建和绑定转移到被依赖对象类的外部来实现。

在上述的实例中,Order类所依赖的对象SqlServerDal的创建和绑定是在Order类内部进⾏的。

事实证明,这种⽅法并不可取。

既然,不能在Order类内部直接绑定依赖关系,那么如何将SqlServerDal对象的引⽤传递给Order类使⽤呢?依赖注⼊(DI):它提供⼀种机制,将需要依赖(低层模块)对象的引⽤传递给被依赖(⾼层模块)对象。

通过DI,我们可以在Order类的外部将SqlServerDal对象的引⽤传递给Order类对象。

那么具体是如何实现呢?⽅法⼀构造函数注⼊构造函数函数注⼊,毫⽆疑问通过构造函数传递依赖。

因此,构造函数的参数必然⽤来接收⼀个依赖对象。

那么参数的类型是什么呢?具体依赖对象的类型?还是⼀个抽象类型?根据DIP原则,我们知道⾼层模块不应该依赖于低层模块,两者应该依赖于抽象。

那么构造函数的参数应该是⼀个抽象类型。

我们再回到上⾯那个问题,如何将SqlServerDal对象的引⽤传递给Order类使⽤呢?⾸选,我们需要定义SqlServerDal的抽象类型IDataAccess,并在IDataAccess接⼝中声明⼀个Add⽅法。

public interface IDataAccess{void Add();}然后在SqlServerDal类中,实现IDataAccess接⼝。

public class SqlServerDal:IDataAccess{public void Add(){Console.WriteLine("在数据库中添加⼀条订单!");}}接下来,我们还需要修改Order类。

public class Order{private IDataAccess _ida;//定义⼀个私有变量保存抽象//构造函数注⼊public Order(IDataAccess ida){_ida = ida;//传递依赖}public void Add(){_ida.Add();}}OK,我们再来编写⼀个控制台程序。

一文说透依赖注入

一文说透依赖注入

一文说透依赖注入控制反转在整洁架构中非常重要,而大部分现代框架的设计思想都是暗合《架构整洁之道》的,因此,在大部分现代框架中,都内置了依赖注入机制,以支持控制反转。

什么是依赖?每个软件,都是由很多“组件”构成的。

这里的“组件”是指广义的组件——组成部件,它可能是函数,可能是类,可能是包,也可能是微服务。

软件的架构,就是组件以及组件之间的关系。

而这些组件之间的关系,就是(广义的)依赖关系。

依赖有多重要?软件的维护工作,本质上都是由“变化”引起的,只要软件还活着,我们就无法对抗变化,只能顺应它。

而组件之间的依赖关系决定了变化的传导范围。

一般来说,当被依赖的组件变化时,其依赖者也会随之变化。

软件开发最怕的就是牵一发而动全身。

所幸,并不是每次变化都必然会传导给它的依赖者们。

对于具体实现细节的修改,只要没有改变其外部契约(可简单理解为接口),其依赖者就不需要修改。

对于更大规模的修改,比如更换计费策略,我们是不是就无法控制其传播了?也不见得。

只要我们的设计能让两者的接口保持一致,就可以把变化控制在尽可能小的范围内。

整洁架构与IoC对于减少变更传播的方式,Bob 大叔在《架构整洁之道》中做过系统性的阐述,如下图:在这张图中,我们要注意箭头的指向,箭头的指向就是依赖的方向。

我们看到,所有的依赖都指向了用例(领域服务)并最终指向了业务实体。

这样的架构很理想,因为业务实体的变化通常都比较少,即使变,通常也是必要的、无法回避的变化。

反之,支持新的用户界面、换数据库、换外部系统等方面的变化都只会在很小的范围内传播。

回顾一下你维护过的系统的各种变更,都属于哪一类呢?这张图看起来很美,却和我们传统的编程方式截然不同。

以展示器为例,在传统的编程方式下,我们需要在展示器中创建用户界面类的实例,并且设置用户界面的值以及接收来自用户界面的事件。

这时候,我们就不得不让展示器“引用”用户界面的类,这样就产生了一个从展示器指向用户界面的依赖,破坏了架构的整洁性。

依赖注入怎样实现有几种方式

依赖注入怎样实现有几种方式依赖注入(Dependency Injection,简称DI)是指通过外部将依赖对象传递给一个类,而不是在类内部创建依赖对象的方式。

它是面向对象编程中的一种设计模式,旨在降低类与类之间的耦合度,提高代码的可测试性和可维护性。

依赖注入有多种实现方式,下面将详细介绍其中的几种方式。

1. 构造函数注入(Constructor Injection):构造函数注入是最常见和推荐的依赖注入方式之一、通过在类的构造函数参数中声明需要依赖的对象,然后在类的实例化过程中将依赖对象传递给构造函数。

这种方式可确保依赖对象在类的创建时就被注入,并且在类的生命周期中都存在。

2. Setter方法注入(Setter Injection):Setter方法注入是另一种常见的依赖注入方式。

通过在类中定义与依赖对象对应的setter方法,在使用类的时候通过调用setter方法将依赖对象注入。

这种方式相较于构造函数注入更加灵活,可以在任何时候替换依赖对象,并且不需要修改类的构造函数。

3. 接口注入(Interface Injection):接口注入是一种相对较少使用的依赖注入方式。

它要求类实现一个特定的接口,在调用类的方法时,通过接口的方法将依赖对象注入。

这种方式相较于构造函数注入和setter方法注入更为灵活,但也增加了代码的复杂度和维护成本。

4. 注解注入(Annotation Injection):注解注入是一种基于注解的依赖注入方式。

通过在类或者类的成员上添加特定的注解来标识依赖对象,然后在运行时使用注解处理器来解析注解,并将依赖对象注入到相应的位置。

注解注入方式相较于前面几种方式更加灵活,对类的改动要求较小,但需要依赖于特定的注解框架。

除了上述几种依赖注入方式,还有一些其他的实现方式,如上下文注入、工厂方法注入等。

不同的依赖注入方式适用于不同的场景,选择合适的方式需要结合具体的业务需求和技术架构来决定。

什么是依赖注入——本文作者的思想太经典了

什么是依赖注入?首先,马桶是一个大大的容器,能够容纳各种秽物。

而且您应该明确这个观点:这个技术的根本目的就是让您和您拉的屎能够轻松的进行分离,不至于在您排泄的过程中拉的满裤子都是而无法清理,否则您就得通过其他手段,例如拿纸重新擦屁股,或者漂洗内裤乃至丢弃这样不可重用,且浪费资源的方法来解决拉屎难,且大便与屁眼儿无法及时分离的困难。

解决这个问题的根本思想就是设计一个接口――屁眼儿,让您进食之后能够及时将大便排泄出体外。

所以,我们进行消化这个动作是依赖于屁眼的,同时在另一方面,在马桶容器这边,需要提供一个能够接纳屁眼放置在其内的空间,以便能够通过存储大便的这个方法来获得对人拉屎这个动作的控制,人就是这样依赖于屁眼将大便注入到马桶里的。

如果我们把目光放的更宽泛些,您也许会发现,人吃进去的是蔬菜,是鱼肉,怎么到马桶这样一个输出端就变成屎了呢,按道理,蔬菜和鱼肉排泄在马桶里还应该是原来的东西啊?如果您仔细理解了:容器本身是不对接口有任何实现的,即马桶本身不具备能将屎变成蔬菜和鱼肉的功能。

您发散下思维也许看的更清楚。

农民伯伯会把这些屎尿播撒在田地里,然后它们滋润着蔬菜苗们的生长,给周围鱼塘供以新鲜食料…从这个角度来看,注意,农民伯伯也有屁眼,所以他肯定实现了屁眼这个接口。

具体将屎尿转化为蔬菜鱼肉这个过程其实是由农民伯伯来具体实现的,我们所要做的就是将其过程逆化,其结果就是有人在一边种,有人在另一边吃,本来农民是天下的主人,我们这帮孙子在人头上吃喝拉撒,您瞧,这在根本意义上不就是自然而然的控制反转么?还有一点注意,屎和蔬菜鱼肉在根本上没有任何区别,只是对于人这一端来说需要加以判断;识别出来它们是蔬菜鱼肉才敢吃,否则吃到屎就该报错了。

这点和Spring技术本身没有任何出入。

写在前面的话昨天在博客园上看到一篇博文,名为“什么是依赖注入?(来听一个笑话)”[点击这里访问]。

可以看出,作者是想以一种轻松幽默的方式对依赖注入的思想进行一个阐述。

依赖注入和控制反转概念

依赖注入和控制反转概念一. 依赖注入1、依赖注入(Dependency Injection,简称DI)是什么?依赖注入是一种软件架构模式,它允许我们把一些模块或技术的实现和使用分离开来,从而使代码更易于维护和重用。

这种模式将系统所依赖的关键组件以及他们之间的依赖关系注入其中,而不是让类自己创建或查找所需组件,从而使得系统更加灵活,容易重构,可以使用不同的实现,避免了紧耦合。

2、依赖注入的作用是什么?依赖注入的主要作用有以下几点:(1)解耦:将实例的创建和它的使用分离,使得类之间的依赖关系更加松散,并且更容易实现复用。

(2)灵活:因为创建和使用实例分离,所以不同的实现可以被注入,使得系统更加灵活,不同的实现可以替换掉而不需要修改代码。

(3)测试:可以通过依赖注入来替换真实的组件,从而使得测试更加容易,实现在不依赖真实的组件和资源的情况下进行测试。

3、依赖注入的实现依赖注入一般可以有以下几种实现:(1)构造函数注入:给构造函数传入所需的对象,由构造函数来完成组装,这种方式比较简单,但是也会出现一些问题,比如要注入很多对象会导致构造函数参数过多,使得代码不易读和维护。

(2)Setter方式注入:通过提供Setter函数来完成注入,比如JavaBean中的Setter函数,这种方式的好处是,注入的灵活,可以逐个对象进行注入,也可以把所有的对象一次性注入,但是这种方式依赖于Setter函数,有些情况下不灵活,比如某些对象不适合用Setter函数进行注入。

(3)接口注入:这种方式是对于Setter注入的一种扩展,它将Setter函数定义在接口中,这样就不依赖于Setter函数,而是更为精细的控制,类只需要实现接口即可。

4、依赖注入的优势(1)配置灵活:可以在不同的配置文件中使用不同的实现,比如不同的数据库、不同的缓存服务器,而无需修改代码;(2)代码重用:可以实现代码的复用,比如对多个类使用一个服务,而不需要重复实现相同的代码;(3)易于测试:可以避免使用真实组件,使用Mock对象来模拟环境,更容易完成测试;(4)可读性:可以更好的控制类之间的依赖关系,从而使得代码更加清晰易读,更容易理解和维护。

依赖注入模式在Java开发中的应用

依赖注入模式在Java开发中的应用Java是一个广泛使用的编程语言,许多企业将其作为其主要的开发语言。

在Java开发中,依赖注入模式已经成为了一种流行的设计模式,它是一种使得类之间依赖更加稳定,灵活和可扩展的方式。

本文将深入分析依赖注入模式在Java开发中的应用,包括其定义、作用、使用方法和其它相关知识点。

依赖注入模式的定义依赖注入模式是一种将依赖关系从调用方转移给外部一个容器的设计模式,该容器通过构造函数、Setter方式或其他方式注入它所需要的依赖关系。

该容器通过将所需组件提供给在运行时被需要的对象,为对象提供了解耦。

简而言之,依赖注入就是更加灵活地管理类之间的关系。

依赖注入模式的作用在Java开发中,依赖注入模式可以具有以下优点:1. 灵活性:依赖关系可以在运行时被注入,使得在不同的场景下对同一对象的依赖关系可以发生变化。

2. 可测试性:对于单元测试Java类时,可以使用依赖注入来实现更好效果的mock对象的创建,使得测试的更加准确。

3. 降低耦合性:通过依赖注入实现组件的准确关系,组件之间解耦,通过这样的途径我们可以避免代码和组件的改动。

4. 易于扩展性:在运行过程中,通过注入新的依赖关系或替换老的依赖关系来扩展程序的功能。

依赖注入模式的使用方法Java开发中,依赖注入模式的实现通常有以下两个步骤:1. 使用接口描述组件我们在程序设计中,经常使用接口来描述组件的职责。

为程序中的组件定义一个接口,该接口应该描述组件的基本行为,并对其进行准确描述。

对于使用多个接口的每个组件,这将有助于管理它们的依赖性并使程序更加灵活。

2. 使用一个容器将组件注入到程序中我们可以使用Java中的一个容器将接口和实现类打包到一个组件中。

Spring是一个知名的依赖注入框架,其基本思想是将所需组件与容器分离出来,在运行时由容器注入对象。

容器用于掌握组件的关系并随时将这些依赖关系注入到程序中。

依赖注入模式的其他知识点1. 构造函数注入构造函数注入是依赖注入模式中的一种类型。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验十二依赖注入的应用
一、实验目的
1.掌握设值注入和注解注入方式
2.熟悉不同类型值的注入设置方法
3.掌握自动扫描机制
二、实验环境
1.Tomcat
2. MyEclipse
三、实验描述
已知一个添加了spring支持的Java项目中包含一个DAO接口和一个业务接口,分别如下所示:
//Dao接口
public interface PersonDao {
public void insert();
}
//业务接口
public interface PersonService {
public void persist();
public void printMsg();
}
说明:
1.已知业务接口实现类中有三个字段:name、age和DAO接口(PersonDao)类型对象。

2.DAO接口实现类的功能是输出“持久化以上数据”字符串;业务接口实现类的persist()调用DAO接口的insert();printMsg() 的功能是打印业务接口实现类中的name和age 属性值。

3.在客户端分别调用业务接口的persist()和printMsg()方法,运行结果如下图所示:
要求:分别使用属性注入方式、自动扫描机制以及@Resource实现如上图所示的运行结果注意:使用自动扫描机制时使用构造器初始化name和age属性值
实验步骤:
①创建一个java项目
②搭建Spring运行环境
③创建一个Dao接口及其实现类
④创建一个业务接口及其实现类
⑤在src目录下新建一个Spring的配置文件
⑥创建测试类。

相关文档
最新文档