我目前正在实施基本解决方案,通过反射在Asp.Net Core中加载服务,而不必传递每种类型。 为了有一些摆动空间,我创建了一个静态助手,使用新的核心反射类型返回汇编类型:
internal static class ReflectionTypeHelper
{
private static readonly Assembly _currentAssembly = typeof(ServiceContainerInitializer).GetTypeInfo().Assembly;
internal static IReadOnlyCollection<Type> ScanAssembliesForTypes(Func<Type, bool> predicate)
{
var result = new List<Type>();
var appAssemblies = GetApplicationAssemblies();
foreach (var ass in appAssemblies)
{
var typesFromAssembly = ass.GetTypes().Where(predicate);
result.AddRange(typesFromAssembly);
}
return result;
}
private static IEnumerable<Assembly> GetApplicationAssemblies()
{
var consideredFileExtensions = new[]
{
".dll",
".exe"
};
var result = new List<Assembly>();
var namespaceStartingPart = GetNamespaceStartingPart();
var assemblyPath = GetPath();
IEnumerable<string> assemblyFiles = Directory.GetFiles(assemblyPath);
var fileInfos = assemblyFiles.Select(f => new FileInfo(f));
fileInfos = fileInfos.Where(f => f.Name.StartsWith(namespaceStartingPart) && consideredFileExtensions.Contains(f.Extension.ToLower()));
// Net.Core can't load the Services for some reason, so we exclude it at the moment
//fileInfos = fileInfos.Where(f => f.Name.IndexOf("Services", StringComparison.OrdinalIgnoreCase) == -1);
foreach (var fi in fileInfos)
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(fi.FullName);
result.Add(assembly);
}
return result;
}
private static string GetNamespaceStartingPart()
{
var fullNamespace = _currentAssembly.FullName;
var splittedNamespace = fullNamespace.Split('.');
var result = string.Concat(splittedNamespace[0], ".", splittedNamespace[1]);
return result;
}
private static string GetPath()
{
var codeBase = _currentAssembly.CodeBase;
var uri = new UriBuilder(codeBase);
var result = Uri.UnescapeDataString(uri.Path);
result = Path.GetDirectoryName(result);
return result;
}
}
正如您可能在代码注释中看到的那样,我无法加载&#34; Services&#34; -Assembly,我是从ASP.NET核心Web应用程序中创建的。净核心)&#34; - 项目模板。
不幸的是,异常是非常通用的
无法加载文件或程序集&#39; Argusnet.Pis.Services, Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;。
此外,文件按预期存在。 我确实在GitHub上找到了一些关于这个主题的提示,但它们都在候选版本中得到了解决。
有趣的是,所有其他装配都按照您的预期工作,因此必须有关于此装配类型的特定内容?
答案 0 :(得分:0)
无法加载的原因之一可能是编译期间选择的目标处理器架构不匹配。 Argusnet.Pis.Services
可能使用x86配置进行编译,尝试加载的客户端应用程序可能在编译期间使用x64选项构建,或者反过来。在构建之前,确保两个项目都设置了相同的选项(x86或x64)。否则,请尝试使用Any CPU
选项构建它们。