Spring.NET学习笔记9——打造简易的依赖注入框架(练习篇) Level 100
我们在第三篇中学习里一个简易的IoC框架。今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 。
我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法);可以获取属性和属性的类型(GetProperties方法)。通过Activator的CreateInstance(Type type, params object[] args)方法可以创建带参数构造函数的实例。通过SetValue方法可以给属性赋值,这样一来,我们就上次的代码稍加改造就可以实现属性的注入了。
下面是完成的代码:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class PersonDao
{
private int intProp;
public PersonDao(int intProp)
{
this.intProp = intProp;
}
public Person Entity { get; set; }
public override string ToString()
{
return "构造函数参数intProp为:" + this.intProp;
}
}
public class ObjectFactory
{
private IDictionary<string, object> objectDefine = new Dictionary<string, object>();
private ObjectFactory(string fileName)
{
InstanceObjects(fileName); // 实例IoC容器
DiObjects(fileName); // 属性注入
}
private static ObjectFactory instance;
private static object lockHelper = new object();
public static ObjectFactory Instance(string fileName)
{
if (instance == null)
{
lock (lockHelper)
{
instance = instance ?? new ObjectFactory(fileName);
}
}
return instance;
}
/**//// <summary>
/// 实例IoC容器
/// </summary>
/// <param name="fileName"></param>
private void InstanceObjects(string fileName)
{
XElement root = XElement.Load(fileName);
var objects = from obj in root.Elements("object")
select obj;
//无参构造函数
objectDefine = objects.Where(obj =>
obj.Element("constructor-arg") == null).ToDictionary(
k => k.Attribute("id").Value,
v =>
{
string typeName = v.Attribute("type").Value;
Type type = Type.GetType(typeName);
return Activator.CreateInstance(type);
}
);
//有参构造函数
foreach (XElement item in objects.Where(obj =>
obj.Element("constructor-arg") != null))
{
string id = item.Attribute("id").Value;
string typeName = item.Attribute("type").Value;
Type type = Type.GetType(typeName);
var args = from property in type.GetConstructors()[0].GetParameters()
join el in item.Elements("constructor-arg")
on property.Name equals el.Attribute("name").Value
select Convert.ChangeType(el.Attribute("value").Value,
property.ParameterType);
object obj = Activator.CreateInstance(type, args.ToArray());
objectDefine.Add(id, obj);
}
}
/**//// <summary>
/// 属性注入
/// </summary>
/// <param name="fileName"></param>
private void DiObjects(string fileName)
{
XElement root = XElement.Load(fileName);
var objects = from obj in root.Elements("object")
select obj;
foreach (KeyValuePair<string,object> item in objectDefine)
{
foreach (var el in objects.Where(e =>
e.Attribute("id").Value == item.Key).Elements("property"))
{
Type type = item.Value.GetType();
//获取属性
foreach (PropertyInfo property in type.GetProperties())
{
if (property.Name == el.Attribute("name").Value)
{
if (el.Attribute("value") != null)
{
//设置属性值
property.SetValue(item.Value,
Convert.ChangeType(el.Attribute("value").Value,
property.PropertyType), null);
}
else if (el.Attribute("ref") != null)
{
object refObject = null;
if (objectDefine.ContainsKey(el.Attribute("ref").Value))
{
refObject = objectDefine[el.Attribute("ref").Value];
}
//设置关联对象属性
property.SetValue(item.Value, refObject, null);
}
}
}
}
}
}
/**//// <summary>
/// 获取对象
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public object GetObject(string id)
{
object result = null;
if (objectDefine.ContainsKey(id))
{
result = objectDefine[id];
}
return result;
}
}
<?xml version="1.0" encoding="utf-8" ?>
<objects>
<object id="person" type="SpringNetMyDi.Person, SpringNetMyDi">
<!--属性值类型注入-->
<property name="Name" value="Liu Dong"/>
<property name="Age" value="27"/>
</object>
<object id="personDao" type="SpringNetMyDi.PersonDao, SpringNetMyDi">
<!--构造器注入-->
<constructor-arg name="intProp" value="1"/>
<property name="Entity" ref="person" />
</object>
</objects>
class Program
{
static void Main(string[] args)
{
ObjectFactory factory = ObjectFactory.Instance(@"F:\Exercise\SpringNet\Step1\SpringNet_Lesson9\SpringNetMyDi\Objects.xml");
PersonDao dao = (PersonDao)factory.GetObject("personDao");
Console.WriteLine("姓名:" + dao.Entity.Name);
Console.WriteLine("年龄:" + dao.Entity.Age);
Console.WriteLine(dao);
Console.ReadLine();
}
}
输入结果:
代码下载
返回目录
Spring.NET学习笔记9——打造简易的依赖注入框架(练习篇) Level 100相关推荐
- Spring.NET学习笔记——目录(原)
目录 前言 Spring.NET学习笔记--前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1--控制反转(基础篇) Level 200 Spring.NET学习笔 ...
- Spring.NET学习笔记10——方法的注入(基础篇) Level 200
多数用户都会将容器中的大部分对象布署为singleton模式.当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协 ...
- Spring MVC 学习笔记 对locale和theme的支持
Spring MVC 学习笔记 对locale和theme的支持 Locale Spring MVC缺省使用AcceptHeaderLocaleResolver来根据request header中的 ...
- Spring Cloud 学习笔记(四)-Spring Cloud Hystrix
Spring Cloud 学习笔记(四)-Spring Cloud Hystrix 由于前一阵子项目的原因,今天才继续弄上,今天想学习一下Hystrix组件 这个组件还挺抽象的,最开始我一直没太明白, ...
- Spring Boot学习笔记-实践建言
2019独角兽企业重金招聘Python工程师标准>>> 本文延续<Spring Boot学习笔记-快速示例>,从开发指南中摘出一些实践经验可供参考.这也是笔者看到的眼前一 ...
- Spring.NET学习笔记——前言
Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入.面向方面编程(AOP).数据访问抽象及ASP.NET扩展等等.Sprin ...
- Spring Boot学习笔记-进阶(3)
文章目录 Spring Boot学习笔记-进阶(3) 一.Spring Boot与缓存 二.Spring Boot与消息 三.Spring Boot与检索 四.Spring Boot与任务 异步任务 ...
- Spring Boot学习笔记-基础(2)
Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...
- Spring Boot学习笔记(1)
文章目录 Spring Boot学习笔记(1) Spring Boot 整合 JSP Spring Boot HTML Thymeleaf 常用语法 Spring Boot 数据校验 Spring B ...
最新文章
- 手动部署OpenStack环境(一:Virtual Box 5.1 环境的安装及配置)
- 【大牛云集】悉尼科技大学ReLER实验室介绍
- js控制audio音量_js控制html5 audio音频暂停播放
- 如何在私有链部署智能合约
- 斐波那契数列的鬼畜的性质
- java 昵称1到32位字符_Java期末考试编程题复习
- python中exit 的作用_Python退出命令-为什么要使用这么多?何时使用每个命令?
- ActiveMq工作笔记002---Centos7.3安装ActiveMq
- Learn OpenGL(四)——片段着色器(Fragment Shader)
- matlab无法打开.m文件查看
- js 实现PHP中的in_array()
- 【Latex简历模板】OverLeaf平台筛选出的部分中英文简历模板
- 云端服务器与传统的独立主机服务器有什么区别
- 创客集结号:国内无人机技术发展的难点有哪些?
- 十二载征程犹未止,看今朝星光尽闪耀丨万字长文回顾2023数据技术嘉年华
- unity3D地形编辑器—Terrain
- html密码域的type属性,查看网页黑点密码 将type=password中password修改成为text
- 一个mysql事务引发的思考(血案)
- IPV6重复地址检测(DAD)
- android studio 初始化必备控件 > Failed to notify project evaluation listener. > javax/xml/bind/annotation/
热门文章
- android app功能 配置,配置安装时分发 | Android 开发者 | Android Developers
- 基于ESP32的竞赛裁判系统功能调试-计时线圈功能
- 创办智能车竞赛平台,十五年无间断,育人数十万
- AD9833所产生的高频信号质量分析
- 快速下载Centos7:Centos镜像地址(阿里云镜像)
- vue indev.html,webpack多入口热加载很慢
- 太阳电池板特性实验_汕头市通风柜厂家报价-广州中增实验室设备
- python实现案例_基于Python实现相关分析案例
- Linux下新增的代码放哪儿,linux – 如何在QEMU源代码中添加新设备?
- cnn 反向传播推导_深度学习中的参数梯度推导(三)下篇