网上有 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.dllSpring.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 -入门篇的更多相关文章

  1. 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透

    前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定 ...

  2. 老司机带你玩转面试(3):Redis 高可用之主从模式

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  3. 老司机带你玩转面试(4):Redis 高可用之哨兵模式

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  4. 老司机带你玩转面试(5):Redis 集群模式 Redis Cluster

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  5. 老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化

    引言 今天周末,我在家坐着掐指一算,马上又要到一年一度的金九银十招聘季了,国内今年上半年受到 YQ 冲击,金三银四泡汤了,这就直接导致很多今年毕业的同学会和明年毕业的同学一起参加今年下半年的秋招,这个 ...

  6. 老司机带你玩转web service

    当大型需求被数个公司分割开来,各公司系统相互交换数据的问题就会接踵而来.毕竟是多家不同的公司的产品,研发开发语言.采用技术框架基本上是百花齐放.怎样让自家系统提供的服务具有跨平台.跨语言.跨各种防火墙 ...

  7. 编程老司机带你玩转 CompletableFuture 异步编程

    本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...

  8. 老司机带你走进Core Animation

    为什么时隔这么久我又回来了呢? 回来圈粉. 开玩笑的,前段时间ipv6被拒啊,超级悲剧的,前后弄了好久,然后需求啊什么的又超多,所以写好的东西也没有时间整理.不过既然我现在回来了,那么这将是一个井喷的 ...

  9. 老司机带你开飞机 一: mssql on linux 安装指导

    通常在本机开发环境中需要搭建所有的服务,还要修改本地的hosts,实在是不胜其烦.如今有了docker,完全不用污染本地环境,且看老司机带你搭建一个asp.net core的开发环境集群.愿你走出虚拟 ...

随机推荐

  1. MySQL升级指南

    一 .MySQL升级 1.官方升级策略 注意 升级过程中必须使用具有管理权限的MySQL帐户来执行SQL语句. 1.升级方法 逻辑升级: 涉及使用 mysqldump从旧的MySQL版本导出现有数据 ...

  2. 使用Ajax解析数据遇到的问题

    数据格式 我最近在使用JQuery的$.ajax访问后台的时候,发现竟然无法解析返回的数据,具体的错误记不清了(以后在遇到问题先截个图),可以在浏览器的Console中看到一个错误,但是去看这条请求是 ...

  3. 转 :关于springmvc使用拦截器

    原博客: http://elim.iteye.com/blog/1750680 SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的 ...

  4. 利用Linux系统生成随机密码的9种方法

    Linux操作系统的一大优点是对于同样一件事情,你可以使用高达数百种方法来实现它.例如,你可以通过数十种方法来生成随机密码.本文将介绍生成随机密码的十种方法. 1. 使用SHA算法来加密日期,并输出结 ...

  5. Foglight 5.6.7 控制台jboss报404

    Foglight 5.6.7 控制台jboss报404 [终极问题原来就一数据库权限问题!下文是由问题源找到的类似的dell support的相关文章,但却是关于sql server error的,感 ...

  6. 「小程序JAVA实战」java-sesion的状态会话与无状态会话(38)

    转自:https://idig8.com/2018/09/02/xiaochengxujavashizhanjava-sesiondezhuangtaihuihuayuwuzhuangtaihuihu ...

  7. **类的起源--type

    通过type类的实例化,创建新的类. #!/usr/bin/env python # Version = 3.5.2 def func(self): print('Hello,{}'.format(s ...

  8. 小米手机Root 刷机

    需要备份的资料: miui系统资料:电话.短信.便签,有小米云账号wifi下自己会备份好的. 应用数据:微信.qq 聊天记录: UC浏览器收藏夹. root后, rootexplorer,选择某个文件 ...

  9. Adjacent Bit Counts(uvalive)

    For a string of n bits x1, x2, x3,…, xn, the adjacent bit count of the string (AdjBC(x)) is given by ...

  10. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 12—Support Vector Machines 支持向量机

    Lecture 12 支持向量机 Support Vector Machines 12.1 优化目标 Optimization Objective 支持向量机(Support Vector Machi ...