Spring.NET学习笔记8——集合类型的注入(基础篇)
我们在第三篇中学习里一个简易的IoC框架。今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 。
我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法);可以获取属性和属性的类型(GetProperties方法)。通过Activator的CreateInstance(Type type, params object[] args)方法可以创建带参数构造函数的实例。通过SetValue方法可以给属性赋值,这样一来,我们就上次的代码稍加改造就可以实现属性的注入了。
下面是完成的代码:
Domain
- 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;
- }
- }
ObjectFactory
- 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;
- }
- }
App.config
- <?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>
Program
- 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2008-03-26 c# 二分查找
2008-03-26 几种字符串反转方法效率比较
2008-03-26 C#反转字符串效率最高的方法