我有一个引用.NET 4.0程序集的WPF / C#应用程序。但是,在应用程序中是一个文本编辑器,需要显示与.NET 3.5程序集绑定的C#intellisense。因此,我希望能够在运行时加载适当的.NET 3.5程序集。但是,当我尝试使用时:
Assembly.Load()
Assembly.LoadFile()
Assembly.LoadFrom()
我总是从GAC获得最新版本。阅读他们的MSDN页面,看起来不幸的是设计。
我尝试按照stack overflow post中提出的解决方案进行操作。但是,链接的网页解决方案不起作用,远程处理过程似乎有点矫枉过正。有没有人知道在运行时加载旧.NET程序集的更好和/或更简单的方法?
答案 0 :(得分:1)
默认情况下,您无法在.NET Framework版本4上加载为以前版本的.NET框架创建的程序集。
但是,有一个配置属性允许:http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx
将以下行放在app.config文件中:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true|false" >
</startup>
</configuration>
默认情况下,这是有原因的,但我认为它应该适合您的使用。
答案 1 :(得分:1)
之前我已经完成了这项工作,虽然来自GAC中没有的程序集:我从字节数组中加载了Mine,但我可以很容易地拥有相同程序集的不同版本。
解决方案是处理AppDomain的AssemblyResolve事件,以便确保返回所需的程序集。在你的情况下,这可能相当简单,因为你只关心做这个特定的调用。其余的时间你采取默认设置,甚至根本不处理。
一个可能的例子可能是:
public DoSomething()
{
//Add the handler
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve
//Load your assembly...
}
private System.Reflection.Assembly CurrentDomain_AssemblyResolve(Object sender, ResolveEventArgs e)
{
foreach (System.Reflection.Assembly a In AppDomain.CurrentDomain.GetAssemblies())
{
if (a.FullName == <<The one you need>>) return a
}
}
这很粗糙,但它会给出一个过程的概念 - 你处理assemblylfolve,并返回你需要的东西。处理程序的内容可能会有所不同,因为我不确定您的程序集是否会出现在CurrentDomain.GetAssemblies()
列表中。
可能会有更多微妙的解决方案,可以为您处理GAC版本。
注意:这在.Net 3.5中使用,而不是4,但确实适用于不同版本。您可能需要@Jean的解决方案来在4中加载3.5个程序集。
答案 2 :(得分:1)
您可以在app.config或web.config中使用AssemblyBinding属性,以适当的方式。
例如,我正在与Matlab接口,所以我需要这个......
<loadFromRemoteSources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MWArray" publicKeyToken="E1D84A0DA19DB86F" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.10.0.0" newVersion="2.10.0.0" />
</dependentAssembly>
</assemblyBinding>
因为我使用的Matlab引擎在使用运行时的不同副本的机器上编译(有些疯狂)。
您应该能够修改此代码以满足您的需求。
答案 3 :(得分:0)
我发现的一个部分解决方案是使用Assembly.ReflectionOnlyLoadFrom()。此方法正确加载旧版本的程序集,尽管程序集已加载到仅反射上下文中,这意味着您无法在程序集中执行代码。虽然这不是真正的程序集加载,但它确实启用了我正在处理的大多数智能感知场景。
一个挥之不去的问题是mscorlib。当尝试使用从ReflectionOnlyLoadFrom返回的程序集时,对于较旧版本的mscorlib,会抛出异常:“System.TypeLoadException:无法从程序集'mscorlib加载类型'System.Object',版本= 4.0.0.0,Culture = neutral ,PublicKeyToken = b77a5c561934e089'因为父母不存在。“
答案 4 :(得分:0)
我使用ReflectionOnlyLoadFrom()来解决此问题,以便在只读模式下加载我需要的任何版本的程序集,仅用于反射。当你不能为mscorlib做这个事实时(你可以要求2.0,但你会从调用中得到4.0),我通过过滤根据我需要的版本返回的类型来处理这个问题。毕竟,在这种模式下,你只能使用反射来检查DLL中的类型,而不是用它们做任何其他事情,因此你可以轻松地过滤掉根据需要返回的类型列表。
以下是我到目前为止从mscorlib 4.0中过滤掉的类型,以便在预期使用旧版本的mscorlib时一切正常:
/// <summary>
/// Types to be hidden from .NET mscorlib 4.0 for older versions.
/// </summary>
protected static readonly HashSet<Type> HideMscorlib4Types = new HashSet<Type>
{
// The Action delegates with 0, 2, 3, 4 type parameters were moved from System.Core 3.5 to mscorlib for 4.0
typeof(Action), typeof(Action<,>), typeof(Action<,,>), typeof(Action<,,,>),
// The Func delegates with 1 to 5 type parameters were moved from System.Core 3.5 to mscorlib for 4.0
typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>),
// Other types moved from System.Core 3.5 to mscorlib 4.0
typeof(TimeZoneInfo),
// Hide various types that were new in mscorlib 4.0
typeof(Tuple)
};