Discuz教程网

C#中通过读取配置文件动态创建泛型对象

[复制链接]
authicon 炸酱面 发表于 2010-12-30 12:44:44 | 显示全部楼层 |阅读模式
 在本文中,我们了解了如何通过配置,实现动态创建泛型类型的实例。希望对大家有所帮助。 
 1. 背景
  我们考虑一下这样的一个场景,我们需要开发了一个用于排序的通用的可扩展的库。利用该库,用户可以自定义排序规则(比较大小)以及需要进行排序的数据类型。而同时,我们开发了一个应用程序,在该应用程序中,我们可以让用户选择排序算法来进行排序。由于我们的排序库是可扩展的,因此,在开发应用程序的时候,我们并不知道会有多少种排序算法可供使用,因此我需要通过读取配置文件来动态的加载排序算法。
  2. 排序库Sort.Lib
  在Sort.Lib中,我们定义所有排序算法的通用接口,ISortAlgorithm
  

  1. public interface ISortAlgorithm<T>
  2.   {
  3.   void Sort(List<T> source, Func<T, T, int> compare);
  4.   }
  5.   比如我们有一个排序算法,叫HeapSort,注意该算法可能在Sort.Lib程序集中,也可能不在。
  6.   public class HeapSortAlgorithm<T> : ISortAlgorithm<T>
  7.   {
  8.   public void Sort(List<T> source, Func<T, T, int> compare)
  9.   {
  10.   //TODO: sort the source
  11.   }
  12.   }
复制代码

  3. 应用程序Sort.App
  3.1 动态创建排序算法
  我们知道,要动态的创建HeapSortAlgorithm,只需要获取到其类型,然后利用Activator.CreateInstance就行。例如:
  Activator.CreateInstance(Assembly.Load("assembly").GetType("full type name");
  而在此处,由于我们的HeapSortAlgorithm是个泛型类,则需要给泛型中的T赋予实际的类型。我们可以通过先获取泛型类型,再通过MakeGenericType来创建实际的类型。如下:
  

  1. string assemblyName = string.Empty;
  2.   string fullTypeName = string.Empty;
  3.   //TODO: 读取配置文件,赋值给assemblyName和fullTypeName
  4.   Type[] typeArgs = { typeof(int) };
  5.   Type algTypeGen = Assembly.Load(assemblyName).GetType(fullTypeName);
  6.   //TODO: 判断algTypeGen是否实现了ISortAlgorithm<T>接口
  7.   // 获取HeapSortAlgorithm<int>类型
  8.   Type algType = algTypeGen.MakeGenericType(typeArgs);
  9.   HeapSortAlgorithm<int> heapSortAlg = Activator.CreateInstance(algType);
复制代码

  如此这般,我们的HeapSort算法就可以用上。
  3.2 配置文件
  为了使我们的应用程序能够用上HeapSort,我们将其添加到我们的配置文件中去,如下
  

  1. <SortAlgorithms>
  2.   <Algorithm name="HeapSort" assembly="Sort.Lib" type="Sort.Lib.HeapSortAlgorithm`1" />
  3.   </SortAlgorithms>
复制代码

  注意到配置中type一项设置为Sort.Lib.HeapSortAlgorithm`1,这是因为泛型类HeapSortAlgorithm<T>在运行过程中,它的实际名称是HeapSortAlgorithm`1,这也可以通过typeof(HeapSortAlgorithm<>)得到。(注:关于这点,不知道这个泛型的名称会不会变成HeapSortAlgorithm`2之类的,笔者还不太确定,希望有哪个大大们赐教)
  另:如何去读取配置文件的代码在本文中我就不贴出来了。可以自己写ConfigurationSection类后来获取(推荐),或者直接通过c#中读取XML文件的方式来实现。:)
  3.3 判断类型是否实现泛型接口
  判断algTypeGen是否实现了ISortAlgorithm<T>接口,可以通过对algTypeGen实现的所有接口与ISortAlgorithm<>循环比对即可实现。
  

  1. Type baseSortAlgType = typeof(ISortAlgorithm<>);
  2.   bool isImplemented = algTypeGen.GetInterfaces().Any(x =>
  3.   x.IsGenericType &&
  4.   x.GetGenericTypeDefinition() == baseSortAlgType);
复制代码




上一篇:C#-把Array说透
下一篇:用C#来实现以动画的方式显示图像
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-3 19:09

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表