我正在尝试使用自定义属性定义希望框架容器加载的外部库中的模块。我能够扫描程序集,查找并验证我的类型,并返回示例化IModule的列表。但是,当我尝试解析在外部模块中注册的类型时,该类型无法解析。
面向.Net标准2.0的主库
public static List<IModule> DiscoverContainerModules()
{
var modules = new List<IModule>();
var assemblies = DiscoverAssemblies();
foreach (var assembly in assemblies)
{
modules.AddRange(from type in assembly.GetTypes()
where type.GetCustomAttribute<AppkitModuleAttribute>() != null
where type.IsAssignableTo<IModule>()
select Activator.CreateInstance(type) into module
select module as IModule);
}
return modules;
}
注册模块的扩展方法
public static void UseAppkitModules(this ContainerBuilder builder)
{
var modules = AppkitPluginDiscovery.DiscoverContainerModules();
foreach (var module in modules)
{
builder.RegisterModule(module);
}
}
从面向.Net Core 6.0的托管应用程序
第一个月
最后是另一个.Net Standard 2.0库中的模块示例
[AppkitModule(nameof(DisplayModule))]
public class DisplayModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c =>
{
var conductor = c.Resolve<IConductor>();
var logger = c.Resolve<ILogger>();
return new DisplaySubsystem(
conductor: conductor,
logger: logger);
});
}
}
如果我简单地更新builder.RegisterModule(new DisplayModule()),这个模块就可以正常工作;我已经确认了Load方法是用我的反射方法调用的。为什么用Activator创建模块示例的行为不同。我还确认了程序集是加载的。
我把模块移到了父库中,同样也失败了;我把所有的扩展方法分解成了一个大的代码块,得到了相同的结果;我甚至用Activator创建了示例,得到了相同的结果。
1条答案
按热度按时间kgsdhlau1#
已解决:
问题的根源是我加载和扫描程序集的方法应用了我的自定义属性。我使用的是
Assembly.LoadFile(path)
。它似乎没有提供加载我的模块所需的依赖关系。我更新了该方法以使用Assembly.LoadFrom(path)
,所有模块和类型都能完美地解析。完整解决方案-加载程序集
获取具有自定义属性的程序集
获取具有模块属性的所有类型
生成器扩展
引用程序集中的示例模块
最终容器配置