在加载程序集时,Dot Net Standard的两个实现表现不同。
我已在 DotNetCore 2.0 (dotnet --version
为2.1.4
)和 DotNetFramework 4.6.1 <中测试了以下代码作为控制台应用程序/ p>
private static void Main(string[] args)
{
var referencedType = typeof(SampleType);
var referenceTypeAssembly = referencedType.Assembly;
var manuallyLoadedAssembly_Method_Load = Assembly.Load(referenceTypeAssembly.GetName());
var resolvedType_Method_Load =
manuallyLoadedAssembly_Method_Load.GetType(referencedType.FullName);
var manuallyLoadedAssembly_Method_LoadFile = Assembly.LoadFile(referenceTypeAssembly.Location);
var resolvedType_Method_LoadFile = manuallyLoadedAssembly_Method_LoadFile.GetType(referencedType.FullName);
var manuallyLoadedAssembly_Method_LoadFrom = Assembly.LoadFrom(referenceTypeAssembly.Location);
var resolvedType_Method_LoadFrom = manuallyLoadedAssembly_Method_LoadFrom.GetType(referencedType.FullName);
Console.WriteLine(
$"are equal {nameof(referencedType)}=={nameof(resolvedType_Method_Load)}:" +
$"{referencedType == resolvedType_Method_Load}");
Console.WriteLine(
$"are equal {nameof(referencedType)}=={nameof(resolvedType_Method_LoadFile)}:" +
$"{referencedType == resolvedType_Method_LoadFile}");
Console.WriteLine(
$"are equal {nameof(referencedType)}=={nameof(resolvedType_Method_LoadFrom)}:" +
$"{referencedType == resolvedType_Method_LoadFrom}");
}
结果:
在DotNetCore 2.0中
are equal referencedType==resolvedType_Method_Load:True
are equal referencedType==resolvedType_Method_LoadFile:False
are equal referencedType==resolvedType_Method_LoadFrom:True
在DotNetFramework 4.6.1中
are equal referencedType==resolvedType_Method_Load:True
are equal referencedType==resolvedType_Method_LoadFile:True
are equal referencedType==resolvedType_Method_LoadFrom:True
由于这两个都实现了Dot Net Standard,我对他们运行相同代码的不同事情感到有点困惑。
经过一番调查和阅读后,我最终发现两个版本背后实际上有两个完全不同的实现。
是否有解释为什么在DotNet Standard的不同实现上运行相同代码时出现不一致的情况?
或者更好的问题可能是:
Dot Net Standard是否保证其实现的不同风格之间的行为一致,或仅仅是程序员编码的接口?
如需进一步调查和参考,可能需要查看以下内容:
Here您可以看到Assembly.LoadFile
的 DotNetFramework 实施。
在这里你可以看到同一方法的 DotNetCore 实现。
public static Assembly LoadFile(string path)
{
AppDomain.CheckLoadFileSupported();
Assembly assembly = (Assembly) null;
if (path == null)
throw new ArgumentNullException(nameof (path));
if (PathInternal.IsPartiallyQualified(path))
throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof (path));
string fullPath = Path.GetFullPath(path);
lock (Assembly.s_loadfile)
{
if (Assembly.s_loadfile.TryGetValue(fullPath, out assembly))
return assembly;
assembly = new IndividualAssemblyLoadContext().LoadFromAssemblyPath(fullPath);
Assembly.s_loadfile.Add(fullPath, assembly);
}
return assembly;
}