我正在努力寻找一个好的答案。
我需要扫描所有实现接口IDomainEvent
的类。
问题是这些类型位于不一定加载的项目中。例如,如果我的主程序集是WebApi
,则存在对Application
的依赖,这取决于Domain
,这取决于DomainEvents
因此,我没有一种"简单"的方法来获取实现IDomainEvent
并在*DomainEvents.csproj
项目中的所有类型
是否有任何 nuget 库可以动态浏览所有引用的项目/程序集及其子依赖项,并能够检索实现接口的所有类型?
它在启动时发生一次,所以我不太关心性能。
PS:下面的方法按预期返回0,因为程序集没有加载
var allDomainEventTypes =
AppDomain
.CurrentDomain
.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(t => t.IsAssignableTo(typeof(IDomainEvent)) && !t.IsInterface)
.ToList();
你可以尝试这样的东西
var definitions = typeof(YourTypeInsideAssembly).Assembly.GetImplementationsOf(typeof(IYourInterfaceType));
foreach (var definition in definitions)
{
//Do you thing with definition.
}
这将需要为接口的每个实现指定YourTypeInsideAssembly
。例如,如果您有一个项目有 3 个实现接口的类,另一个项目有 4 个类。您需要为每个项目指定两个类。 我认为这样您也强制加载程序集。
附言
这以前也对我有用:
var allAssemblies = Assembly
.GetEntryAssembly()
.GetReferencedAssemblies()
.Select(Assembly.Load)
.ToArray();
我没有找到任何好东西。 我有以下解决方法(感谢这篇很棒的文章)
public static class AssemblyExtensions
{
public static IEnumerable<Assembly> GetAllAssemblies(this Assembly rootAssembly)
{
var returnAssemblies = new List<Assembly>();
var loadedAssemblies = new HashSet<string>();
var assembliesToCheck = new Queue<Assembly>();
assembliesToCheck.Enqueue(rootAssembly);
while (assembliesToCheck.Any())
{
var assemblyToCheck = assembliesToCheck.Dequeue();
foreach (var reference in assemblyToCheck.GetReferencedAssemblies())
{
var fullName = reference.FullName;
if (!loadedAssemblies.Contains(fullName))
{
var assembly = Assembly.Load(reference);
assembliesToCheck.Enqueue(assembly);
loadedAssemblies.Add(fullName);
returnAssemblies.Add(assembly);
}
}
}
return returnAssemblies;
}
}
它运行良好,因为它能够"递归"加载引用的程序集,因此我可以检索实现给定接口的所有类型。
但是,请注意,引用项目并不一定意味着如果不使用项目中的类,则将引用程序集。
var domainEventTypes =
typeof(Startup)
.Assembly
.GetAllAssemblies()
.SelectMany(x => x.GetTypes())
.Where(t => t.IsAssignableTo(typeof(IDomainEvent)))
.ToList();