Spring.NET学习笔记9——打造简易的依赖注入框架(练习篇) Level 100

  我们在第三篇中学习里一个简易的IoC框架。今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 。
  我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法);可以获取属性和属性的类型(GetProperties方法)。通过
Activator的CreateInstance(Type type, params object[] args)方法可以创建带参数构造函数的实例。通过SetValue方法可以给属性赋值,这样一来,我们就上次的代码稍加改造就可以实现属性的注入了。


  下面是完成的代码:


    public class Person
    
{
        
public string Name getset; }
        
public int Age getset; }
    }


   
public class PersonDao
    
{
        
private int intProp;

        
public PersonDao(int intProp)
        
{
            
this.intProp = intProp;
        }


        
public Person Entity getset; }

        
public override string ToString()
        
{
            
return "构造函数参数intProp为:" + this.intProp;
        }

    }


 


public class ObjectFactory
    
{
        
private IDictionary<stringobject> objectDefine = new Dictionary<stringobject>();

        
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();
        }

    }

 

 输入结果:

 

 

 

 

 代码下载

 

posted @ 2012-02-19 10:14  张良  阅读(138)  评论(0编辑  收藏  举报