删除程序集绑定而不重建
Remove assembly binding without rebuild
我有不使用引用程序集的代码,因为我们决定使用内部邮件。
public static class Helper
{
public static bool UseInternalMail
{
get
{
return Convert.ToBoolean(
ConfigurationManager.AppSettings["UseInternalMail"].ToString();
}
}
public static void SendMail(string message)
{
if(UseInternalMail){
//do via local SMTP
}
else{
//Call a method in 3rd Party assembly, no more using
3rdPartyDll.Send(message);
}
}
}
现在我们不再使用 3rdPartyDll。所以我已经从我在 IIS 中托管的网站的 bin 文件夹中删除了这个 dll。
我们遇到错误
无法加载文件或程序集“3rdPartyDll”
===预绑定状态信息===
LOG:DisplayName = 3rdPartyDll,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null
(完全指定)
日志:Appbase = file:///C:/Client/Web/MyWebsite/
日志:初始 PrivatePath = C:\Client\Web\MyWebsite\bin
调用程序集:MyWebsite,版本=2.0.0.1,文化=中性,
LOG:此绑定在默认加载上下文中启动。
日志:使用应用程序配置文件:C:\Client\Web\MyWebsite\web.config
日志:使用主机配置文件:
日志:使用来自 c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\config\machine.config 的机器配置文件。
日志:此时未将策略应用于引用(私有、自定义、部分或基于位置的程序集绑定)。
日志:之前看到过相同的绑定,但因 hr = 0x80070002 而失败。
为什么代码在执行程序集之前尝试加载程序集。
是否可以在不删除代码并重建的情况下删除程序集?在 web.config?
中删除 assembly/redirect
更新:
尝试使用具有相同方法签名和虚拟实现的假程序集,但没有成功
在 bin\Fake 文件夹
中放置了一个虚拟的假程序集
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="3rdParty" />
<codeBase version="1.0.0.0" href="FakerdParty.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
将引用 dll 的代码移动到另一个永远不会被调用的方法。
例如。
public static class Helper
{
public static void SendMail(string message)
{
if(UseInternalMail)
{
//do via local SMTP
}
else
{
//Call a method in 3rd Party assembly, no more using
SendUsing3rdPartyDll(message);
}
}
private void SendUsing3rdPartyDll(message)
{
3rdPartyDll.Send(message);
}
}
您收到此错误的原因是因为运行时会在每个方法被调用之前对其进行编译,并且它需要编译完整的方法。通过将引用移动到另一个方法,运行时可以编译您的 SendMail 消息。
当您绝对无法更改代码时,另一种方法是提供伪造的程序集。此程序集需要具有相同的名称,并且需要导出项目使用的所有类型和方法,但不需要实现它们。
这仅在当前使用的 3rdPartyDll 没有强名称(即未使用只有原始开发人员拥有的私钥签名)时才有效。
我有不使用引用程序集的代码,因为我们决定使用内部邮件。
public static class Helper
{
public static bool UseInternalMail
{
get
{
return Convert.ToBoolean(
ConfigurationManager.AppSettings["UseInternalMail"].ToString();
}
}
public static void SendMail(string message)
{
if(UseInternalMail){
//do via local SMTP
}
else{
//Call a method in 3rd Party assembly, no more using
3rdPartyDll.Send(message);
}
}
}
现在我们不再使用 3rdPartyDll。所以我已经从我在 IIS 中托管的网站的 bin 文件夹中删除了这个 dll。
我们遇到错误
无法加载文件或程序集“3rdPartyDll”
===预绑定状态信息===
LOG:DisplayName = 3rdPartyDll,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null (完全指定) 日志:Appbase = file:///C:/Client/Web/MyWebsite/ 日志:初始 PrivatePath = C:\Client\Web\MyWebsite\bin
调用程序集:MyWebsite,版本=2.0.0.1,文化=中性,
LOG:此绑定在默认加载上下文中启动。 日志:使用应用程序配置文件:C:\Client\Web\MyWebsite\web.config 日志:使用主机配置文件: 日志:使用来自 c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\config\machine.config 的机器配置文件。 日志:此时未将策略应用于引用(私有、自定义、部分或基于位置的程序集绑定)。 日志:之前看到过相同的绑定,但因 hr = 0x80070002 而失败。
为什么代码在执行程序集之前尝试加载程序集。
是否可以在不删除代码并重建的情况下删除程序集?在 web.config?
中删除 assembly/redirect更新:
尝试使用具有相同方法签名和虚拟实现的假程序集,但没有成功
在 bin\Fake 文件夹
中放置了一个虚拟的假程序集<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="3rdParty" />
<codeBase version="1.0.0.0" href="FakerdParty.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
将引用 dll 的代码移动到另一个永远不会被调用的方法。 例如。
public static class Helper
{
public static void SendMail(string message)
{
if(UseInternalMail)
{
//do via local SMTP
}
else
{
//Call a method in 3rd Party assembly, no more using
SendUsing3rdPartyDll(message);
}
}
private void SendUsing3rdPartyDll(message)
{
3rdPartyDll.Send(message);
}
}
您收到此错误的原因是因为运行时会在每个方法被调用之前对其进行编译,并且它需要编译完整的方法。通过将引用移动到另一个方法,运行时可以编译您的 SendMail 消息。
当您绝对无法更改代码时,另一种方法是提供伪造的程序集。此程序集需要具有相同的名称,并且需要导出项目使用的所有类型和方法,但不需要实现它们。
这仅在当前使用的 3rdPartyDll 没有强名称(即未使用只有原始开发人员拥有的私钥签名)时才有效。