在我的程序中,我使用了许多来源来获取数据。实际的实现并不重要,但它们都实现了一个" Source"在给定特定输入的情况下调用获取数据的接口。
当我需要数据时,我希望一次调用所有数据源并对数据执行某些操作。
目前我这样做:
List<Source> sources = new List<Source>()
sources.Add(new SourceA());
sources.Add(new SourceB());
//...
//----
foreach (Source source in sources)
{
string data = source.getData(input);
//do something with the data
}
问题是我需要硬编码将源插入列表。是否有一种方法(可能使用反射)自动化过程?我希望列表中包含实现“来源”的所有对象。界面 - 无需自己硬编码。
答案 0 :(得分:2)
您可以使用反射在程序集中搜索实现接口和创建实例的类。我会考虑重命名为ISource,除非基类中有共享代码。
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
if (typeof(ISource).IsAssignableFrom(type))
{
sources.Add((ISource)Activator.CreateInstance(type));
}
}
答案 1 :(得分:1)
这是我用来加载存储在外部程序集中的Addons的一些代码。底部的位显示如何使用名为“IWAPAddon”的特定接口获取所有类型,这是您可以使用的代码部分:
//If the plugin assembly is not aleady loaded, load it manually
if ( PluginAssembly == null )
{
PluginAssembly = Assembly.LoadFile( oFileInfo.FullName );
}
if ( PluginAssembly != null )
{
//Step through each module
foreach ( Module oModule in PluginAssembly.GetModules() )
{
//step through the types in each module
foreach ( Type oModuleType in oModule.GetTypes() )
{
foreach ( Type oInterfaceType in oModuleType.GetInterfaces() )
{
if ( oInterfaceType.Name == "IWAPAddon" )
{
this.Addons.Add( oModuleType );
}
}
}
}
}
答案 2 :(得分:0)
根据Slugart的建议:
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.GetInterfaces().Contains(typeof(ISource)) && type.IsInterface == false
{
sources.Add((ISource)Activator.CreateInstance(type));
}
}