如何在 ASP.NET Core 1.0 RC2 中加载程序集
How to load assemblies in ASP.NET Core 1.0 RC2
我正在将我的网络应用程序从 ASP.NET Core RC1 迁移到 RC2。我正在尝试加载我引用的 class 库。
此代码片段不再适用于 RC2:
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// libraryManager is null ....
ILibraryManager libraryManager = app.GetService<ILibraryManager>();
List<Assembly> result = new List<Assembly>();
IEnumerable<Library> libraries = libraryManager.GetLibraries();
IEnumerable<AssemblyName> assemblyNames = libraries.SelectMany(e => e.Assemblies).Distinct();
assemblyNames = Enumerable.Where(assemblyNames, e => e.Name.StartsWith("projectNamespace"));
foreach (AssemblyName assemblyName in assemblyNames)
{
Assembly assembly = Assembly.Load(assemblyName);
.
.
.
}
}
}
我找到了解决办法。我现在使用 DependencyContext
而不是 ILibraryManager
var loadableAssemblies = new List<Assembly>();
var deps = DependencyContext.Default;
foreach (var compilationLibrary in deps.CompileLibraries)
{
if (compilationLibrary.Name.Contains(projectNamespace))
{
var assembly = Assembly.Load(new AssemblyName(compilationLibrary.Name));
loadableAssemblies.Add(assembly);
}
}
我认为 stevo 做出了 2 个错误的假设:
1) 项目命名空间应该是编译库名称的一部分。
2) 编译库名称与二进制名称相同。
当你在项目设置中更改它时,第一个是错误的。
当您在 project.json.
的 buildOptions 中指定它时,第二个是错误的
所以你的想法是对的,但是实现是错误的。
要解决这个问题,我们需要在加载程序集之前忘记按命名空间解析。
我想因为在任何情况下都会加载所有程序集,所以我们不会出现很大的性能延迟。
但这不是万能的……程序集内部可以有多个根命名空间!
所以也许更好的方法是在程序集级别定义一些属性并检查它而不是命名空间。
在任何情况下,如果您想通过程序集名称限制您的搜索,应该像这样:
IEnumerable<AssemblyName> names = DependencyContext.Default.GetDefaultAssemblyNames();
foreach (AssemblyName name in names)
{
if (name.Name.StartsWith("MyRoot") == true)
{
Assembly assembly = Assembly.Load(name);
// Process assembly here...
// I will check attribute for each loaded assembly found in MyRoot.
}
}
我正在将我的网络应用程序从 ASP.NET Core RC1 迁移到 RC2。我正在尝试加载我引用的 class 库。
此代码片段不再适用于 RC2:
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// libraryManager is null ....
ILibraryManager libraryManager = app.GetService<ILibraryManager>();
List<Assembly> result = new List<Assembly>();
IEnumerable<Library> libraries = libraryManager.GetLibraries();
IEnumerable<AssemblyName> assemblyNames = libraries.SelectMany(e => e.Assemblies).Distinct();
assemblyNames = Enumerable.Where(assemblyNames, e => e.Name.StartsWith("projectNamespace"));
foreach (AssemblyName assemblyName in assemblyNames)
{
Assembly assembly = Assembly.Load(assemblyName);
.
.
.
}
}
}
我找到了解决办法。我现在使用 DependencyContext
而不是 ILibraryManager
var loadableAssemblies = new List<Assembly>();
var deps = DependencyContext.Default;
foreach (var compilationLibrary in deps.CompileLibraries)
{
if (compilationLibrary.Name.Contains(projectNamespace))
{
var assembly = Assembly.Load(new AssemblyName(compilationLibrary.Name));
loadableAssemblies.Add(assembly);
}
}
我认为 stevo 做出了 2 个错误的假设:
1) 项目命名空间应该是编译库名称的一部分。
2) 编译库名称与二进制名称相同。
当你在项目设置中更改它时,第一个是错误的。 当您在 project.json.
的 buildOptions 中指定它时,第二个是错误的所以你的想法是对的,但是实现是错误的。
要解决这个问题,我们需要在加载程序集之前忘记按命名空间解析。
我想因为在任何情况下都会加载所有程序集,所以我们不会出现很大的性能延迟。
但这不是万能的……程序集内部可以有多个根命名空间! 所以也许更好的方法是在程序集级别定义一些属性并检查它而不是命名空间。
在任何情况下,如果您想通过程序集名称限制您的搜索,应该像这样:
IEnumerable<AssemblyName> names = DependencyContext.Default.GetDefaultAssemblyNames();
foreach (AssemblyName name in names)
{
if (name.Name.StartsWith("MyRoot") == true)
{
Assembly assembly = Assembly.Load(name);
// Process assembly here...
// I will check attribute for each loaded assembly found in MyRoot.
}
}