程序集中的类列表C#

时间:2017-04-25 10:02:30

标签: c# .net class .net-assembly

我想得到一个程序集中的类列表,作为输出我想要List [接口]而不是List [string],作为"接口"是继承我的程序集的类的接口。我不知道我的问题是否有意义但如果有人有答案我会非常感激。 我已经尝试过这个解决方案:List of classes in an assembly,但是它给出了一个包含类名称的列表[string],因为我不需要帮助,因为我需要从我的界面继承的类列表。 谢谢你,祝你有个美好的一天:)

作为我的问题的编辑,我使用了activator.createinstance(类型t)来创建我的类的实例,所以这里是代码:

   Assembly assembly = typeof(Interface1<double, double>).Assembly;

   List<Interface> Classes = new List<Interface>();

   foreach (Type type in assembly.GetExportedTypes())

   {
      var Attributes = type.GetCustomAttributes<FilterAttribute>();
      //select the classes with attribute [Filter]

      if (Attributes.Any())

      {
                TypeOfFilters.Add(type);

      }

      foreach (var i in TypeOfFilters)

      {
            var inst = Activator.CreateInstance(i);

            Classes.Add((Interface) inst);


      }

   }

我收到错误&#34; System.IO.FileNotFoundException:无法加载文件或程序集&#34;

2 个答案:

答案 0 :(得分:2)

这里有一个小班,几个星期后,当我感到无聊的时候,我正在唠叨,这就是你所要求的 - 如果我正确地理解了这个问题。

您的应用程序必须实现IPlugin,并且必须放入&#34;插件&#34;执行目录中的文件夹。

public interface IPlugin
{
    void Initialize();
}
public class PluginLoader
{
    public List<IPlugin> LoadPlugins()
    {
        List<IPlugin> plugins = new List<IPlugin>();

        IEnumerable<string> files = Directory.EnumerateFiles(Path.Combine(Directory.GetCurrentDirectory(), "Plugins"),
            "*.dll",
            SearchOption.TopDirectoryOnly);

        foreach (var dllFile in files)
        {
            Assembly loaded = Assembly.LoadFile(dllFile);

            IEnumerable<Type> reflectedType =
                loaded.GetExportedTypes().Where(p => p.IsClass && p.GetInterface(nameof(IPlugin)) != null);

            plugins.AddRange(reflectedType.Select(p => (IPlugin) Activator.CreateInstance(p)));
        }

        return plugins;
    }
}

根据Paul在评论中的建议,这是使用MEF的变体,引用System.ComponentModel.Composition命名空间。

namespace ConsoleApplication18
{
    using System;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using System.IO;
    using System.Linq;

    public interface IPlugin
    {
        void Initialize();
    }
    class Program
    {
        private static CompositionContainer _container;
        static void Main(string[] args)
        {
            AggregateCatalog catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Directory.GetCurrentDirectory(), "Plugins")));

            _container = new CompositionContainer(catalog);

            IPlugin plugin = null;
            try
            {
                _container.ComposeParts();

                // GetExports<T> returns an IEnumerable<Lazy<T>>, and so Value must be called when you want an instance of the object type.
                plugin = _container.GetExports<IPlugin>().ToArray()[0].Value;
            }
            catch (CompositionException compositionException)
            {
                Console.WriteLine(compositionException.ToString());
            }

            plugin.Initialize();
            Console.ReadKey();
        }
    }
}

和DLL文件 - 还引用System.ComponentModel.Composition命名空间来设置ExportAttribute

namespace FirstPlugin
{
    using System.ComponentModel.Composition;

    [Export(typeof(IPlugin))]
    public class NamePlugin : IPlugin
    {
        public void Initialize() { }
    }
}

答案 1 :(得分:0)

如果我理解你的问题应该是这样的:

var list = System.Reflection.Assembly.GetTypes().Where(x => typeof(IYourInterface).IsAssignableFrom(x)).ToList();