Com*_*nDk 9 c# .net-core asp.net-core
我正在构建一个Web应用程序,我想要单独关注,即在不同的项目中进行抽象和实现.
为了实现这一点,我尝试实现一个组合根概念,其中所有实现必须具有ICompositionRootComposer
注册服务,类型等的实例.
public interface ICompositionRootComposer
{
void Compose(ICompositionConfigurator configurator);
}
Run Code Online (Sandbox Code Playgroud)
在构建层次结构中直接引用的项目中,将ICompositionRootComposer
调用实现,并在基础IoC容器中正确注册服务.
当我尝试在项目中注册服务时出现问题,我在其中设置了一个后期构建任务,将构建的dll复制到Web项目的调试文件夹:
cp -R $(TargetDir)"assembly and symbol name"* $(SolutionDir)src/"webproject path"/bin/Debug/netcoreapp1.1
Run Code Online (Sandbox Code Playgroud)
我正在加载程序集:(灵感:如何加载位于.net核心控制台应用程序中的文件夹中的程序集)
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,我就可以加载程序集并调用项目ICompositionRootComposer
实现.
但问题是它似乎没有认出我的任何类型.
用调用我的配置器时
configurator.RegisterTransiantService<IFoo, Foo>();
Run Code Online (Sandbox Code Playgroud)
它应该在IoC中注册IFoo和Foo.
但是在调试时我无法获取类型的信息,即通过Visual Studio Code中调试控制台中的typeof(Foo).
Necromancing.
您可以为旧的Assembly.LoadFile创建一个包装类来执行此操作.
这样做的另一个好处是,您可以通过在旧代码库中应用搜索和替换更改来保持向后兼容dotnet-none-core.
您需要System.Runtime.Loader
通过nuget 添加.
namespace System.Reflection
{
public class Assembly2
{
public static System.Reflection.Assembly LoadFile(string path)
{
System.Reflection.Assembly ass = null;
#if NET_CORE
// Requires nuget - System.Runtime.Loader
ass = System.Runtime.Loader.AssemblyLoadContext.Default
.LoadFromAssemblyPath(path);
#else
ass = System.Reflection. Assembly.LoadFile(path);
#endif
// System.Type myType = ass.GetType("Custom.Thing.SampleClass");
// object myInstance = Activator.CreateInstance(myType);
return ass;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我找到了解决问题的方法。
事实证明,我将该属性PreserveCompilationContext
设置为 true,这就是调试器不会注册我手动复制的程序集的原因。当我从 Web 项目 csproj 文件中删除该属性时,一切正常。
归档时间: |
|
查看次数: |
8968 次 |
最近记录: |