c# - 如何更新 .NET Core 和 .NET Framework 应用程序之间共享的程序集

标签 c# .net .net-core .net-standard

我有在 .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 在同一位置查找此程序集?

最佳答案

史蒂夫用他的评论为我指明了正确的方向。这是带有示例的完整答案。我在 .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 方法中直接引用共享库,则应用程序会尝试在注册事件处理程序之前加载程序集。

现在,当我编译应用程序并运行它们时,我得到以下输出。

Registering Resolving Handler...

Creating shared library...

The version is 1.0.10765

Press Enter key to continue...

现在让我们将新版本的共享库放入 SharedAssemblies 文件夹中,并删除与应用程序一起发布的共享库。现在这是输出。

Creating shared library...

Resolving MyLibrary, Version=1.0.10765.0, Culture=neutral, PublicKeyToken=null

Resolving to path C:...\SharedLibrary\SharedAssemblies\MyLibrary.dll

The version is 1.0.10930

Press Enter key to continue...

Core 和 Framework 应用程序的结果相同。请注意,我们可以将较新版本的程序集放到 SharedAssemblies 文件夹中,它仍然可以正确加载。这是我正在寻找允许更新共享库的结果。现在我可以将它放在一个位置并更新两个应用程序。但是如果出于某种原因我只想更新一个应用程序,我仍然可以将所需的版本放入应用程序的 bin 文件夹中。这是可行的,因为程序集解析器将首先在本地 bin 中查找,如果没有在共享位置找到,则只从共享位置拉取。

你可以在 this GitHub project 上获得所有的源代码来玩这个.

关于c# - 如何更新 .NET Core 和 .NET Framework 应用程序之间共享的程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52192229/

相关文章:

c# - 在 Compact Framework 中使用 WCF 错误

.net - 表达式中未定义的函数 'Nz'

.net - MSBuild ItemGroup,不包括 .svn 目录和文件

.net-core - 如何从命令行运行 .NET Core 控制台应用程序

serilog - Dotnet 核心、JSNLog 和 Serilog 之间的不兼容

c# - NativeWindow WndProc 未接收消息

C# - 测试通用私有(private)函数

c# - 如何在非主线程中获取剪贴板数据?

c# - 代码在本地 Windows 2008 上运行正常,但无法在 Azure 云上的应用程序数据中创建子文件夹

c# - 是否可以在 Windows docker 容器中运行的 dotnet 核心应用程序中使用 EPPlus?