我有在.NET Core 2.1中开发的应用程序A和在.NET Framework 4.7.1中开发的应用程序B。它们具有使用.NET Standard 2.0开发的共享库/程序集。这很好用,我可以编译该库的单个实例,并在应用程序A和应用程序B之间共享它。但这需要每个应用程序bin文件夹中的程序集两个副本。如果将应用程序A和应用程序B部署在同一台机器上,我想在单个位置更新共享程序集的单个实例,并同时更新应用程序A和应用程序B。假设一个正在使用.NET Core,而另一个正在使用.NET Framework,那么应用程序A和应用程序B是否可以在同一程序集中查找相同的位置?
答案 0 :(得分:1)
史蒂夫(Steve)的评论向我指出了正确的方向。这是带有示例的完整答案。我在.NET Core和.NET Framework中编写了一个简单的控制台应用程序,该应用程序调用共享库。该库仅返回要在控制台应用程序中显示的库的版本号。如您所见,这将使测试更加容易。这是共享库的全部操作。
using System.Diagnostics;
namespace MyLibrary
{
/// <summary>
/// This is a shared library that returns the assemblies version
/// </summary>
public class SharedLib
{
public string GetProductVersion()
{
System.Reflection.Assembly assembly =
System.Reflection.Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
string version = fvi.ProductVersion;
return version;
}
}
}
共享库针对.net标准2.0进行编译。为了进行测试,我将其作为NuGet软件包发布在本地NuGet服务器上。然后,我在核心和框架应用程序中包含了NuGet软件包。两种应用程序几乎相同。这是代码。
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Registering Resolving Handler...");
AppDomain.CurrentDomain.AssemblyResolve += MyHandler;
Console.WriteLine("Creating shared library...");
SharedLibWrapper sharedLib = new SharedLibWrapper();
Console.WriteLine("The version is {0}", sharedLib.Version);
Console.WriteLine("Press Enter key to continue...");
Console.ReadLine();
}
static string GetSharedAssemblyPath()
{
string relativePath = @"..\..\..\SharedAssemblies\";
return Path.GetFullPath(relativePath);
}
static Assembly MyHandler(object source, ResolveEventArgs e)
{
Console.WriteLine("Resolving {0}", e.Name);
if (e.Name.Contains("MyLibrary"))
{
string path = GetSharedAssemblyPath() + @"MyLibrary.dll";
Console.WriteLine("Resolving to path {0}", path);
return Assembly.LoadFile(path);
}
return null;
}
}
此代码添加了一个AssemblyResolve处理程序,以便在应用程序找不到程序集的情况下,处理程序将尝试解析该程序集。在这种情况下,我两个应用程序都位于解决方案根目录下的SharedAssemblies文件夹中。
您会注意到,我将共享库放在了类包装器中。这是我获得解决方案的唯一途径。如果我直接在Main方法中引用了共享库,则应用程序将尝试在事件处理程序注册之前加载程序集。
现在,当我编译应用程序并运行它们时,将得到以下输出。
注册解析处理程序...
正在创建共享库...
版本为1.0.10765
按Enter键继续...
现在,让我们将共享库的新版本放入SharedAssemblies文件夹中,并删除随应用程序发布的版本。现在这是输出。
正在创建共享库...
正在解析MyLibrary,版本= 1.0.10765.0,文化=中性, PublicKeyToken =空
解析到路径C:... \ SharedLibrary \ SharedAssemblies \ MyLibrary.dll
版本为1.0.10930
按Enter键继续...
对于Core和Framework应用程序,结果是相同的。请注意,我们可以将新版本的程序集删除到SharedAssemblies文件夹中,并且仍可以正确加载。这是我寻找允许更新共享库的结果。现在,我可以将其放在一个位置并更新两个应用程序。但是,如果由于某种原因我只想更新一个应用程序,我仍然可以通过将所需的版本放在应用程序的bin文件夹中来进行更新。之所以可行,是因为程序集解析器将首先在本地容器中查找,并且仅在未找到共享位置的情况下才从共享位置中拉出。
您可以在this GitHub project上获取所有源代码并使用它。