我的应用程序和测试依赖于.NET供应商库和System.Data.SQLite。供应商库也依赖于System.Data.SQLite,但版本不同。我的应用程序包括:
使用dependentAssembly
修改C#WinForm应用程序的app.config很容易。我们将较旧的SQLite DLL放在子目录中,并使用以下命令重定向到它:
<dependentAssembly>
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" />
<codeBase version="1.0.98.0" href="SQLite_v1.0.98\System.Data.SQLite.dll" />
</dependentAssembly>
但是我宁愿避免使用C ++应用程序的.config文件。试图让.config文件用于自定义测试运行器可执行文件一直是一个真正的痛苦。因此,我尝试用一个预加载步骤替换app.config重定向,该步骤在供应商库执行之前被调用:
public ref class AssemblyResolver
{
public:
static Reflection::Assembly^ ResolveEventHandler(Object^ sender, ResolveEventArgs^ args)
{
if (args->Name != "System.Data.SQLite, Version=1.0.98.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139")
return nullptr;
auto sb = gcnew Text::StringBuilder();
sb->Append(GetAssemblyDirectory());
sb->Append("\\SQLite_v1.0.98\\System.Data.SQLite.DLL");
return Reflection::Assembly::LoadFrom(sb->ToString());
}
//Returns the containing directory of the assembly that contains the function.
static String^ GetAssemblyDirectory()
{
auto codeBase = Reflection::Assembly::GetExecutingAssembly()->CodeBase;
auto uri = gcnew UriBuilder(codeBase);
auto path = Uri::UnescapeDataString(uri->Path);
return System::IO::Path::GetDirectoryName(path);
}
};
void preload()
{
AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler(AssemblyResolver::ResolveEventHandler);
}
除了在调用preload()
之前应用程序使用SQLite 1.0.105的情况下,此方法有效。我宁愿不必强制所有应用程序在启动应用程序时首先调用preload()
,所以我问是否有更好的方法。
例如,有一种简单的方法可以将供应商库(实际上是一组DLL)放入带有较旧的SQLite.dll的子目录中,以便供应商DLL将使用该较旧的SQLite,但所有其他的1st方代码(DLL和EXE)将使用较新的SQLite?同样,最好不需要C ++应用程序和单元测试运行程序的.config文件。
更新:
两个版本的SQLite DLL具有相同的名称。官方System.Data.SQLite.dll
。我还有另一个供应商依赖性,我已经更新为使用与我们使用的相同的SQLite版本(105)。基于@MickyD的评论,我尝试将SQLite文件更改为其他名称:System.Data.SQLite.105.dll
。但是然后我得到了一个错误:
无法加载文件或程序集'System.Data.SQLite, 版本= 1.0.105.2,文化=中性,PublicKeyToken = db937bc2d44ff139' 或其依赖项之一。找到的程序集的清单定义 与程序集引用不匹配。
由于没有严格定义此其他供应商依赖项,因此我可以对其进行反编译/重新编译(实际上,我已经将其更新为105)。因此,我尝试更新名称以添加.105后缀:
.assembly extern System.Data.SQLite.105
{
.publickeytoken = (DB 93 7B C2 D4 4F F1 39 ) // ..{..O.9
.ver 1:0:105:2
}
哪个给了我一个错误重新编译:
将'B.il'组装为DLL->'B.dll'
源文件是ANSI
B.il(57):错误:.assembly extern中标记“ .105”处的语法错误 System.Data.SQLite.105
*****故障*****
动oil动静!