反射IOC

1,配置文件
<?xml version="1.0" encoding="utf-8" ?>
  <configuration>
     <configSections>
        <sectionGroup name="IocInCSharp">
           <section name="objects" type="IocInCSharp.ConfigHandler, MainApp" />
        </sectionGroup>
     </configSections>
     <IocInCSharp>
        <objects>
         <object name="SayHello" assembly="SayHello.dll" typeName="IocInCSharp.SayHello">
            <property name="HelloGenerator" assembly="HelloGenerator.dll"         typeName="IocInCSharp.CnHelloGenerator"></property>
         </object>
        </objects>
     </IocInCSharp>
  </configuration>

2,自定义对象
internal class ConfigInfo
 {
    public ArrayList Objects = new ArrayList();

    public ObjectInfo FindByName(string name)
    {
       foreach(ObjectInfo o in Objects)
       {
          if(o.name == name)
           return o;
       }

       return null;
    }

 }

 internal class ObjectInfo
 {
    public string name;
    public string assemblyName;
    public string typeName;
    public ArrayList properties = new ArrayList();
 }

 internal class PropertyInfo
 {
    public string propertyName;
    public string assemblyName;
    public string typeName;
 }

3,参数转换
 public class ConfigHandler:IConfigurationSectionHandler
 {
    public object Create(object parent, object configContext, System.Xml.XmlNode section)
    {
       ObjectInfo info;
       PropertyInfo propInfo;

       ConfigInfo cfgInfo = new ConfigInfo();

       foreach(XmlNode node in section.ChildNodes)
       {
          info = new ObjectInfo();
          info.name = node.Attributes["name"].Value;
          info.assemblyName = node.Attributes["assembly"].Value;
          info.typeName = node.Attributes["typeName"].Value;

          foreach(XmlNode prop in node)
          {
             propInfo = new PropertyInfo();
             propInfo.propertyName = prop.Attributes["name"].Value;
             propInfo.assemblyName = prop.Attributes["assembly"].Value;
             propInfo.typeName = prop.Attributes["typeName"].Value;
             info.properties.Add(propInfo);
         }

        cfgInfo.Objects.Add(info);
     }

     return cfgInfo;
    }
 }

4,工厂方法
          /// <summary>
          /// Assembly.LoadFile()用于将外部文件装载进来;assembly.CreateInstance()根据装载进来的程序集创建一指定类型的对象;
          /// t.InvokeMember(prop.propertyName, ........BindingFlags.SetProperty, null, o, new Object[] {p})
          /// 利用反射机制对创建出来的对象设置属性值。
          /// </summary>
          /// <param name="name"></param>
          /// <returns></returns>
  public static object Create(string name)
  {
     Assembly assembly;
     object o = null;
     object p;

     string rootPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +   Path.DirectorySeparatorChar;

     //指定配配置路径中对象,调用参数转换方法
     ConfigInfo cfgInfo = (ConfigInfo)ConfigurationSettings.GetConfig("IocInCSharp/objects"); 
     //获得指定对象
     ObjectInfo info = cfgInfo.FindByName(name);

     if(info != null)
     {
        //加载程序集
        assembly = Assembly.LoadFile(rootPath + info.assemblyName);
        //创建SayHello主程序实例
        o = assembly.CreateInstance(info.typeName);

        Type t = o.GetType();

        for(int i=0; i<info.properties.Count; i++)
        {     
           PropertyInfo prop = (PropertyInfo)info.properties[i];
           //加载程序集
           assembly = Assembly.LoadFile(rootPath + prop.assemblyName);
           //创建HelloGenerator附程序实例
           p = assembly.CreateInstance(prop.typeName);
           //使用反射动态调用类成员
           t.InvokeMember(prop.propertyName, 
            BindingFlags.DeclaredOnly | 
            BindingFlags.Public | BindingFlags.NonPublic | 
            BindingFlags.Instance | BindingFlags.SetProperty, null, o, new Object[] {p});

        }
     }
     return o;
    }
 }

posted on 2011-04-13 12:12  netyaya  阅读(305)  评论(0)    收藏  举报

导航