老司机带你玩Spring.Net -入门篇
网上有 Spring.Net 的相关的很多介绍的文章还有实践例子,推荐个还不错的博客 Spring.Net 学习笔记 。以前对 Spring.Net 算是有过一面之缘,但却迟迟未真正相识。在网上有太多的五花八门的文章来介绍它,讴歌它,也有很多的在线学习文档。很多人也尝试去学习这个神奇的框架,你会发现网上的资料虽然很多,但有些很枯燥的术语频繁的出现在文章中导致理解起来很吃力,这也让很多只是希望入门的人难以掌握而无奈半途而废。刚好在一个项目中需要整合这个框架,抽了点时间研究下,也算小有成果,今天偷着闲写个简单的示例来介绍下什么是 Spring.Net 、怎么去用它。
关于什么是 Spring.Net ,这里直接引用一段网上的介绍:
- Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。Spring.NET以Java版的Spring框架为基础,将Spring.Java的核心概念与思想移植到了.NET平台上。
- 企业级应用一般由多个物理层组成,每个物理层也经常划分为若干功能层。不同层次之间需要相互协作,例如,业务服务层一般需要使用数据访问层的对象来实现某个用例。不管应用程序如何构建,最终都会表现为一系列相互协作的对象,这些对象一起组成了完整的应用程序。所以我们说,应用程序中的对象之间相互具有依赖性。
- .NET平台为构建应用程序提供了丰富的功能,从非常基础的基元类型和基础类库(以及定义新类的方法),到功能完善的应用程序服务器和Web框架,都有很好的支持。但.NET平台本身并没有提供任何方式来管理基础的应用模块并将它们组合为一个相互协作的整体,只能依靠架构师或开发人员去创建(一系列)应用程序。诚然,目前有很多设计模式可用于业务系统的设计,我们可以使用这些模式将各种类或对象组合成能够正常工作的完整应用。工厂、抽象工厂、Builder、装饰及服务定位器(Service Locator)等模式已被现今的软件开发行业广泛接受和采用(这也许正是这些模式最早被定型为模式的原因)。这些模式都非常好,但也不过是些已命名的最佳编程方法,在对这些模式的介绍中一般还会说明它们是作什么用的、最好应用到什么场合、可以解决什么问题等等。我们可以从许多书籍和wiki上找到这些模式,然后仔细研读,然后实现在我们自己的应用中。
- Spring.NET的IoC容器所解决的,正是如何在企业应用中将类、对象和服务组合成应用程序的问题。IoC容器通过很正统(按:formalized,言下之意是这些方式都是已经定型了的、经过了业界多年考验的)的方式将分散的组件组合成完整的应用程序。Spring.NET框架所采用的,都是被业界无数应用程序考验多年的、已经被定型为设计模式的最佳编程方式,实际上,这些模式已经成为我们架构和开发时的法典,而通过Spring.NET,我们可以直接将它们整合到自己的应用程序中。目前已有很多组织和机构用Spring框架开发出了强壮的、维护性好的应用程序,这确实是一件非常好的事情。
上面这一坨其实阅读起来不会那么晦涩难懂,讲白了就是在说(吹) Spring.Net 是如何去实现业务层之间的解耦, Spring.Net 提供的功能(比如 DI 、IoC),其实从刚入门来说 DI、和 IoC 就是 Spring.Net 的核心体现,知道怎么用,就算是可以入门了,这个也是我写这篇文章的目的。
使用 Spring.Net 时需要去在配置文件(App.config)上进行配置,然后跟其它第三方框架一样需要引入相关的程序集(类库)。这里我创建一个 WinForm 项目来作为本次 Demo 的示例演示。创建完成项目之后,会产生一个 App.config 配置文件,把这个配置内容放到 <configuration></configuration> 节点之间
- <configSections>
- <sectionGroup name="spring">
- <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
- <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
- </sectionGroup>
- </configSections>
- <spring>
- <context>
- <resource uri="config://spring/objects"/>
- </context>
- <objects xmlns="http://www.springframework.net">
- <description>An example that demonstrates simple IoC features.</description>
- </objects>
- </spring>
这个配置主要是初始化 IApplicationContext ,其实就是初始化容器让我们可以根据这个容器通过代码获取到指定的对象。这里主要提下 Spring.Core ,Spring.Core 程序集是 Spring.Net 控制反转 (IoC,也叫依赖注入)功能实现的基础。
这里我们就把配置文件的内容给完成了,简单吧!现在我们引入 Common.Logging.dll / Spring.Core.dll 这两个程序集,然后就可以开始进行代码的实现了。
首先我们在 WinForm 窗体中添加一个按钮,双击按钮在后台代码加入创建容器的代码
- IApplicationContext ctx = ContextRegistry.GetContext();
容器创建完成,接着我们分别创建 PersonService 类 和 接口类 IPersonService
PersonService 继承 IPersonService 接口,并实现内部的一个 Show() 方法,代码如下 :
- public class PersonService:IPersonService
- {
- public void Show()
- {
- Console.WriteLine("Spring.Net Demo..");
- }
- }
PersonService
- public interface IPersonService
- {
- void Show();
- }
IPersonService
在没有使用 Spring.Net 之前我们在窗体后台代码调用 PersonService 都是需要先(New)实例化对象,再调用内部的方法
- PersonService p = new PersonService();
- p.Show();
现在我们使用 Spring.Net 的容器来创建对象。创建对象之前需要在配置文件中加入 <object></object> 节点对象
- <objects xmlns="http://www.springframework.net">
- <description>An example that demonstrates simple IoC features.</description>
- <object name="PersonService" type="SpringNetDemo.PersonService, SpringNetDemo">
- </object>
- </objects>
加入这个对象节点之后,我们可以就可以通过以下代码来获取这个对象:
- IPersonService personService =(IPersonService)ctx.GetObject("PersonService");
- personService.Show();
从这段代码来看,你会发现其实这就是一种抽象工厂的实现。当然这个时候你可能会十分的好奇后面这种方式和实例化对象有什么本质上的区别,其实一开始我也是懵逼的。 先不急,我们先把这个问题留着,接着去探索下如何在类中实现属性注入。
我们在 PersonService 类中加入这些自定义属性
- private PersonDal PersonDal { get; set; }
- private string ServerName { get; set; }
- private int Age { get; set; }
然后在配置文件 PersonService 的对象节点加入自定义属性
- <property name="ServerName" value="许大虾"/>
这个时候 ServerName 这个属性值会经过容器初始化成 "许大虾" ,这样就完成了属性注入。那么问题就来了,在类中经常会使用构造函数来初始化值,这个时候不是很别扭了吗?别慌, Spring.Net 绝对的强大,现在我们来看下构造函数的实现。首先我们还是一样的在 App.config 中加入构造函数的属性
- <constructor-arg name="age" value="18"/>
然后在 PersonService 类中加入一个构造函数
- public PersonService(int age)
- {
- Age = age;
- }
这个时候就可以跟普通的属性注入一样对 age 的值进行初始化。到这边我们就可以把 Spring.Net 的容器 、IoC、 DI 都用了一遍了。最后我们还需要解决一个问题,如何进行复杂的属性注入。比如传统的三层架构都有 UI 层 、业务层,UI层一般都是通过依赖业务层对业务层的方法进行实例化调用,那能否直接通过 Spring.Net 的依赖注入把这两个业务层都进行彻底解耦呢?答案当然是可以的, Spring.Net 真是神一样的框架,实现这个自然是没问题。
我们建立一个新的类 PersonDal
- public class PersonDal
- {
- public string Uname { get; set; }
- }
然后在 App.config 中加入这个对象
- <object name="PersonDal" type="SpringNetDemo.PersonDal, SpringNetDemo">
- <property name="Uname" value="许大虾666"/>
- </object>
这个时候还需要在 App.config 中的 PersonService 对象节点去关联 PersonDal
- <property name="PersonDal" ref="PersonDal"/>
- <object name="PersonService" type="SpringNetDemo.PersonService, SpringNetDemo">
- <constructor-arg name="age" value="18"/><!--构造函数注入-->
- <property name="ServerName" value="许大虾"/><!--属性注入-->
- <property name="PersonDal" ref="PersonDal"/>
- </object>
接着在 PersonService 中去访问 PersonDal 里面这个自定义属性
- Console.WriteLine(PersonDal.Uname);
最后来看下实际的 Demo 效果
这样就能够把这个复杂注入的问题给实现了!返回最初的问题,这个时候再去看这个问题就不是问题了。在刚入门的时候并不需要你能很深的把 Spring.Net 所有原理都掌握了,毕竟这也不太现实,只要把 Spring.Net 的容器,IoC,DI 都拿来实现一遍并且能体会出一些实际的应用场景那就是这篇文章的目的了。
老司机带你玩Spring.Net -入门篇的更多相关文章
- 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透
前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定 ...
- 老司机带你玩转面试(3):Redis 高可用之主从模式
前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...
- 老司机带你玩转面试(4):Redis 高可用之哨兵模式
前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...
- 老司机带你玩转面试(5):Redis 集群模式 Redis Cluster
前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...
- 老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化
引言 今天周末,我在家坐着掐指一算,马上又要到一年一度的金九银十招聘季了,国内今年上半年受到 YQ 冲击,金三银四泡汤了,这就直接导致很多今年毕业的同学会和明年毕业的同学一起参加今年下半年的秋招,这个 ...
- 老司机带你玩转web service
当大型需求被数个公司分割开来,各公司系统相互交换数据的问题就会接踵而来.毕竟是多家不同的公司的产品,研发开发语言.采用技术框架基本上是百花齐放.怎样让自家系统提供的服务具有跨平台.跨语言.跨各种防火墙 ...
- 编程老司机带你玩转 CompletableFuture 异步编程
本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...
- 老司机带你走进Core Animation
为什么时隔这么久我又回来了呢? 回来圈粉. 开玩笑的,前段时间ipv6被拒啊,超级悲剧的,前后弄了好久,然后需求啊什么的又超多,所以写好的东西也没有时间整理.不过既然我现在回来了,那么这将是一个井喷的 ...
- 老司机带你开飞机 一: mssql on linux 安装指导
通常在本机开发环境中需要搭建所有的服务,还要修改本地的hosts,实在是不胜其烦.如今有了docker,完全不用污染本地环境,且看老司机带你搭建一个asp.net core的开发环境集群.愿你走出虚拟 ...
随机推荐
- Linux: su sudo sudoer
日常操作中为了避免一些误操作,更加安全的管理系统,通常使用的用户身份都为普通用户,而非root.当需要执行一些管理员命令操作时,再切换成root用户身份去执行. 普通用户切换到root用户的方式有:s ...
- find命令中的print0和xargs -0
看到命令find . -name checkout-cache -f -- 不明白其中-print0和 xargs -0的用法.查了一下,转载一篇备忘. xargs命令的作用是将参数列表转换成小块分段 ...
- curl_setopt设置发送cookie信息
1.php curl访问会话传递问题 curl_setopt($ch , CURLOPT_COOKIE , 'PHPSESSID=A7281E0926CB37D791AD464CDD646CF2') ...
- Linux Centos 7 RabbitMQ 安装
下载地址:http://www.rabbitmq.com/releases/rabbitmq-server/ 找到rabbitmq-server-3.6.15-1.el7.noarch.rpm 第一步 ...
- ffmpeg源码分析二:main函数和transcode函数 (转2)
原帖地址:http://blog.csdn.net/austinblog/article/details/24804455 首先从main函数看起,关键解释部分已加注释,该函数在ffmpeg.c文件中 ...
- UNIX网络编程——客户/服务器心搏函数 (转)
下面是关于回送客户和服务器程序开发一些简单的心搏函数.这些函数可以发现对端主机或到对端的通信路径的过早失效. 在给出这些函数之前我们必须提出一些警告.首先,有人会想到使用TCP的保持存 ...
- Linux安装MariaDB+初始化数据库
背景说明: 在数据库中,mysql的是常用的数据库之一:作为一款开源的软件被广大公司所使用. 但是,mysql在被Oracle公司收购后,难免在以后会有取消开源的问题.所以急需一款新的数据库产品替换m ...
- easyui隐藏列
1.$("#test-datagrid").datagrid('hideColumn', 'password');其中第二个参数为对应的域,即field 2. <th dat ...
- ASP .NET core 入门基础内容备份
model 里边设置主键 : [key]可以自定义主键 默认是名称为ID类型为int的字段 设置显示格式: [DisplayFormat(DataFormatString="{0:显示的格式 ...
- [JS] 让人犯晕的JavaScript变量赋值
变量赋值 本文转载自http://hellobug.github.io/blog/javascript-variable-assignment/ 开始之前先来几个例子,确保起始点是晕的状态- :P 例 ...