程序集 C# 中 类 的列表
List of classes in an assembly C#
我想在程序集中获取 类 的列表,作为输出我想要一个 List[Interface] 而不是 List[string],因为 "Interface" 是继承自的接口我的程序集的 类。我不知道我的问题是否有意义,但如果有人有答案,我将非常感激。
我已经尝试过这个解决方案: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);
}
}
我收到错误 "System.IO.FileNotFoundException : Could not load file or assembly"
如果我正确理解你的问题,应该是这样的:
var list = System.Reflection.Assembly.GetTypes().Where(x => typeof(IYourInterface).IsAssignableFrom(x)).ToList();
这里有一点 class 几个星期前我无聊的时候突然想到,这就是你要问的 - 如果我理解正确的话。
您的应用程序必须实现 IPlugin,并且必须放在执行目录的 "Plugins" 文件夹中。
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() { }
}
}
我想在程序集中获取 类 的列表,作为输出我想要一个 List[Interface] 而不是 List[string],因为 "Interface" 是继承自的接口我的程序集的 类。我不知道我的问题是否有意义,但如果有人有答案,我将非常感激。 我已经尝试过这个解决方案: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);
}
}
我收到错误 "System.IO.FileNotFoundException : Could not load file or assembly"
如果我正确理解你的问题,应该是这样的:
var list = System.Reflection.Assembly.GetTypes().Where(x => typeof(IYourInterface).IsAssignableFrom(x)).ToList();
这里有一点 class 几个星期前我无聊的时候突然想到,这就是你要问的 - 如果我理解正确的话。
您的应用程序必须实现 IPlugin,并且必须放在执行目录的 "Plugins" 文件夹中。
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() { }
}
}