我正在构建一个 Web 应用程序,在这里我希望分离关注点,即在不同的项目中具有抽象和实现。
为了实现这一目标,我尝试实现组合根概念,其中所有实现都必须具有
当我尝试在一个项目中注册服务时,出现问题,其中我设置了一个后期构建任务,将已构建的dll复制到Web项目的debug文件夹中:
为了实现这一目标,我尝试实现组合根概念,其中所有实现都必须具有
ICompositionRootComposer
的实例来注册服务、类型等。public interface ICompositionRootComposer
{
void Compose(ICompositionConfigurator configurator);
}
在直接在构建层次结构中引用的项目中,将调用ICompositionRootComposer
的实现,并且服务将正确地注册在底层IoC容器中。当我尝试在一个项目中注册服务时,出现问题,其中我设置了一个后期构建任务,将已构建的dll复制到Web项目的debug文件夹中:
cp -R $(TargetDir)"assembly and symbol name"* $(SolutionDir)src/"webproject path"/bin/Debug/netcoreapp1.1
我使用以下代码加载程序集:(灵感来自:.net core控制台应用程序中如何加载位于文件夹中的程序集)
internal class AssemblyLoader : AssemblyLoadContext
{
private string folderPath;
internal AssemblyLoader(string folderPath)
{
this.folderPath = Path.GetDirectoryName(folderPath);
}
internal Assembly Load(string filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
AssemblyName assemblyName = new AssemblyName(fileInfo.Name.Replace(fileInfo.Extension, string.Empty));
return this.Load(assemblyName);
}
protected override Assembly Load(AssemblyName assemblyName)
{
var dependencyContext = DependencyContext.Default;
var ressource = dependencyContext.CompileLibraries.FirstOrDefault(r => r.Name.Contains(assemblyName.Name));
if(ressource != null)
{
return Assembly.Load(new AssemblyName(ressource.Name));
}
var fileInfo = this.LoadFileInfo(assemblyName.Name);
if(File.Exists(fileInfo.FullName))
{
Assembly assembly = null;
if(this.TryGetAssemblyFromAssemblyName(assemblyName, out assembly))
{
return assembly;
}
return this.LoadFromAssemblyPath(fileInfo.FullName);
}
return Assembly.Load(assemblyName);
}
private FileInfo LoadFileInfo(string assemblyName)
{
string fullPath = Path.Combine(this.folderPath, $"{assemblyName}.dll");
return new FileInfo(fullPath);
}
private bool TryGetAssemblyFromAssemblyName(AssemblyName assemblyName, out Assembly assembly)
{
try
{
assembly = Default.LoadFromAssemblyName(assemblyName);
return true;
}
catch
{
assembly = null;
return false;
}
}
}
通过这种方式,我能够加载程序集并调用项目的ICompositionRootComposer
实现。
但问题在于它似乎无法识别我的任何类型。
当使用以下方法调用我的配置器时:
configurator.RegisterTransiantService<IFoo, Foo>();
应该在IoC中注册IFoo和Foo。
但是在调试时,我无法通过在Visual Studio Code的调试控制台中使用typeof(Foo)来获取类型信息。
AssemblyLoadContext.Resolving
事件,以帮助加载上下文加载它自己无法加载的程序集。 - ComkeenDk