学习ioc之前先来了解一个依赖导致原则(dip),依赖导致原则是ioc的核心原理。
依赖导致:即上层模块不应该依赖于低层模块,二者应该通过抽象来依赖。依赖于抽象,而不是依赖于细节。
首先来看下面的例子:
1、定义一个接口,封装数据库的基本crud操作,接口定义如下:
2、定义一个mssql类实现该接口,用来模仿sqlrver操作,mssql类定义如下:
3、定义一个oracle类实现该接口,模仿oracle的操作,oracle类定义如下:
4、定义一个控制台应用程序来调用:
常规做法是添加引用,然后直接实例化类,但是这样会依赖于细节实现,现将代码修改如下:
但是这样修改以后,虽然左边是抽象了,但是右边还是依赖于细节。
那就究竟什么是ioc呢?
ioc(inversion of control)即控制反转,是一个重要的面向对象编程的法则来消减程序之间的耦合问题,把程序中上层对下层依赖,转移到一个第三方容器中来装配。ioc是程序设计的目标,实现方式包含依赖注入和依赖查找,在.net中只有依赖注入。
说到ioc,就不能不说di。di:即依赖注入,是ioc的实现手段。
unity是一个ioc容器,用来实现依赖注入(dependency injection,di),减少耦合的,unity出自于伟大的微软。
unity能够做什么呢,列举部分如下:
1.unity支持简单对象创建,特别是分层对象结构和依赖,以简化程序代码。其包含一个编译那些可能存在依赖于其他对象的对象实例机制。
2.unity支持必要的抽象,其允许开发者在运行时或配置去指定依赖关系同时可以简单的管理横切点(aop)。
3.unity增加了推迟到容器组件配置的灵活性。其同样支持一个容器层次的结构。
4.unity拥有服务定位能力,对于一个程序在许多情况下重复使用组件来分离和集中功能是非常有用的。
5.unity允许客户端储存或缓存容器。对于在asp.net web applications中开发者将容器持久化于asp.net中的ssion或application中特别有效。
6.unity拥有拦截能力,其允许开发者通过创建并执行handlers(在方法或属性被调用到达之前)来为已存在的组件增加一个函数,并再次为返回调用结果。
7.unity可以从标准配置系统中读取配置信息,例如:xml文件,同时使用配置文件来配置容器。
8.unity支持开发者实现自定义容器扩展,例如:你可以实现方法来允许额外的对象构造和容器特征,例如缓存。
9.unity允许架构师和开发者在现代化的程序中更简单的实现通用设计模式。
什么情况下要使用unity呢?
1.所构建的系统依赖于健全的面向对象原则,但是大量不同的代码交织在一起而难以维护。
2.构建的对象和类需要依赖其他对象或类。
3.依赖于复杂的或需要抽象的对象。
4.希望利用构造函数、方法或属性的调用注入优势。
5.希望管理对象实例的生命周期。
6.希望能够在运行时管理并改变依赖关系。
7.希望在拦截方法或属性调用的时候为人民服务教案生成一个策略链或管道处理容器来实现横切(aop)任务。
8.希望在web application中的回发操作时能够缓存或持久化依赖关系。
使用管理nuget程序包来安装unity,在项目上右键,选择管理nuget程序包:
在搜索框里面输入unity,点击右侧安装按钮进行安装:
出现以下信息表示安装成功:
先来看看最简单的unity实现方式:
结果:
从结果中可以看出,db是dbmssql类型的实例。
除了使用registertype注册类型以外,还可以注册一个实例,例如:
三种注入方式:构造函数注入、属性注入、方法注入。
iphone接口游褒禅山记教案的实现如下:
iheadphone接口的实现如下:
imicrophone接口的实现如下:
ipower接口的实现如下:
控制台程序调用:
输出结果:
从输出结果中可以看出三种注入方式的执行顺序:先执行构造函数注入,在执行属性注入,最后执行方法注入。
注意:默认情况下如果构造函数上面没有使用特性,那么默认找参数最多的构造函数执行注入。
如果多个不同的实例实现同一个接口,这种情况该怎么注册呢?先来看看下面的代码:
运行结果:
从运行结果中可以看出,后面注册的类型会把前面注册的类型给覆盖掉,那么该如何解决呢?可以通过参数的方式来解决,代码如下:
运行结果:
生命周期及一个对象从创建到释放中间经过的时间。先看下面的代码:
结果:
表明db七一庆祝大会观后感1和db2是两个不同的实例,即默认情况下生命周期是瞬时的,每次都是创建一个新的实例。
container.registertype<idbinterface, dbmssql>(new transientlifetimemanager());表示是瞬时生命周期,默认情况下即这种。
在看下面的代码:
结果:
上图的结果可以看出,db1和db2是同一个实例。
container.registertype(new containercontrolledlifetimemanager())
表示是容器单例,每次都是同一个实例。
在上面的例子中,所有的例子都是一直在依赖于细节,那么怎么解决不依赖于细节呢?答案是只能使用配置文件,配置文件如下:
注意:这个一个单独的配置文件,要把属性里面的复制到输出目录改为始终复制,那么这个配置文件才会生成到debug目录里面。
程序如下:
结果:
观察上面的代码,会发现,如果改成使用配置文件的方式实现的话,代码里面就不会依赖于细节了,只要一个接口类型。既然没有细节了,那么对项目进行如下的改造:把引用里面对细节的引用都去掉(即去掉databa.mssql和databa.oracle),然后debug文件夹里面没有这两个dll了,但是这时需要把这两个dll复制到debug目录下面,否则程序运行的时候会找不到具体实现的类型。这样就意味着程序架构只依赖于接口。
引用里面只要对接口的引用了,没有对具体实现的引用。去掉了对细节的依赖。
注意:使用配置文件实现时,必须把接口的具体实现类复制到程序目录下面会计顶岗实习周记。
如果有额外添加了一种数据库,那么只需要修改配置文件,把新的实现类复制到程序目录下面即可实现程序的升级。
使用配置文件的时候,需要把unityc1425年ontainer容器定义为静态的,这样只需要读取一次配置文件即可。
到此这篇关于c#使用unity实现ioc的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。
本文发布于:2023-04-06 02:10:16,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/9a3a67b5b9e5bcc43ed6d7d72810d32d.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:C#使用Unity实现IOC.doc
本文 PDF 下载地址:C#使用Unity实现IOC.pdf
留言与评论(共有 0 条评论) |