检索从多个程序集实现接口的对象

时间:2012-02-01 23:10:04

标签: c# reflection assemblies

我想检索一个实例化类的枚举,这些类实现了解决方案文件夹中几个程序集的接口。

我有以下文件夹结构(如果这有意义):

Solution
   -SolutionFolder
      - Project1
          - class implementing interface I would like to find
          - other classes

      - Project2
          - class implementing interface I would like to find
          - other classes

   -MainProject
      - classes where my code is running in which I would like to retrieve the list of classes

因此,如果正在实现的接口是ISettings,那么我希望IEnumerable<ISettings>引用该接口的实例化对象。

到目前为止,我已经使用反射从已知的类名中检索实现接口的类:

IEnumerable<ISettings> configuration = 
                (from t in Assembly.GetAssembly(typeof(CLASSNAME-THAT-IMPLEMENTs-INTERFACE-HERE)).GetTypes()
                 where t.GetInterfaces().Contains(typeof(ISettings)) && t.GetConstructor(Type.EmptyTypes) != null
                 select (ISettings)Activator.CreateInstance(t)).ToList();

但这是一个单独的程序集,我实际上不会知道类名。

这可以通过反射实现还是需要更多?

2 个答案:

答案 0 :(得分:1)

只要您只谈论加载到AppDomain中的程序集(它们必须是为了完成您所做的事情),您可以使用类似的东西来迭代它们:< / p>

AppDomain.CurrentDomain
         .GetAssemblies().ToList()
         .ForEach(a => /* Insert code to work with assembly here */);

或者,如果您将它们加载到其他AppDomain中,则可以在上面的AppDomain.CurrentDomain处使用实例。

答案 1 :(得分:0)

要解决此问题,我将解决方案文件夹中每个项目的post build事件设置为将其程序集复制到主项目bin文件夹中的bin文件夹。

post build事件的设置类似于:

copy "$(TargetPath)" "$(SolutionDir)MainProjectName\bin"

然后我使用以下内容从此bin目录中检索程序集文件名(感谢Darin的解决方案here):

string[] assemblyFiles = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"), "*.dll");

然后我使用以下方法检索实现接口ISettings的对象的实现:

IEnumerable<ISettings> configuration = assemblyFiles.Select(f => Assembly.LoadFrom(f))
                .SelectMany(a => a.GetTypes())
                .Where(t => t.GetInterfaces().Contains(typeof(ISettings)) && t.GetConstructor(Type.EmptyTypes) != null)
                .Select(t => (ISettings)Activator.CreateInstance(t));

这允许我添加更多实现设置的项目,而无需重新编译主项目。

此外,我看到的一个替代方法是使用MEF,其中可以找到介绍here