2009-11-24 57 views
3

我有一个场景,我希望有n个类可以查看相同的数据并确定是否需要完成任何工作。工作由团队完成,多个团队可以同时处理数据。我正在考虑为每个将实施CreateWork界面的团队创建一个班级。所有CreateWork类都必须有发言权。目前只有少数,但未来还会有更多。如何在.net中查找程序集中特定接口的所有类.net

我的计划解决方案

For each CreateWork class in assembly 
    class.CheckAndCreateWork(dataIn,returnedCollectionOfWorkToBeDone) 
Next 

须藤代码是否有可能在一个优雅的方式做到这一点的一种设计模式?看起来有点凌乱来循环组件中的每个类。

干杯

回答

9

你可以做到以下几点:

  1. 使用Assembly.GetTypes获取在装配中定义的所有类型。要获取代码正在运行的组件的参考,请使用Assembly.GetExecutingAssembly

  2. 对于每种类型,请检查它是否通过使用Type.IsAssignableFrom来实现所需的接口。

  3. 对于每种适当的类型,请使用Activator.CreateInstance创建一个实例。

这将是大约是这样的(未测试):

foreach(var type in Assembly.GetExecutingAssembly().GetTypes()) { 
    if(typeof(ITheInterface).IsAssignableFrom(type)) { 
     var theInstance=(ITheInterface)Activator.CreateInstance(type); 
     //do something with theInstance 
    } 
} 
+0

+1。我*相信* IsAssignableFrom'比GetInterfaces()慢,Contains(type)'(只适用于接口)。但我可能是错的。 – 2009-11-24 10:14:14

+0

我通常更喜欢IsAssignableFrom,因为它涵盖的范围不仅仅是接口实现,例如它可以告诉您A类是否继承B类。 – Konamiman 2009-11-24 10:21:07

+4

IsAssignableFrom是要走的路,GetInterfaces返回仅在当前类型上定义的接口,但不检查接口继承(IBar:IFoo)。通过发布所有类型的接口链,csc简化了这一点,但并非所有编译器都这样做。 – 2009-11-24 10:21:40

0

这是一个标准的插件任务。那里有很多实现。如果你已经加载了你的assemby,找到你感兴趣的类型很容易 - 你需要使用方法assemlby.GetExportedTypes()Activator.CreateInstance()(假设你有无参数的构造函数 - 否则你可能希望使用容器来注入依赖并建立你的工作实例)

对于简单的情况下,这已经足够:

var workerTypes = assembly.GetExportedTypes() 
    .Where(t => t.IsClass && !t.IsAbstract && typeof(IWorker).IsAssignableFrom(t)); 

foreach (var type in workerTypes) 
{ 
    var worker = (IWorker)Activator.CreateInstance(type); 
    worker.CheckAndCreateWork("Work"); 
} 

获取和装载assemlby是另一个话题。您可以在运行时要么使用负载或Assemlby.LoadFrom()静态链接到您的应用程序并使用这样的事:

var assembly = typeof(SomeClassInTargetAssembly).Assembly; 

动态加载可以通过所有* .DLL文件在特定目录中列举完成(例如,./plugins)是这样的:

​​3210

您可能要分开运行工人装载的流程,以避免装载工人类型的多次(如果你需要在应用程序生命周期运行工不止一次)

1

我认为你应该使用装饰模式。

相关问题