如何在.NET Core和.NET Framework应用程序之间共享程序集

问题描述 投票:4回答:1

我有在.NET Core 2.1和.NET Framework 4.7.1中开发的应用程序B中开发的应用程序A.它们具有使用.NET Standard 2.0开发的共享库/程序集。这很好用,我可以编译这个库的单个实例并在Application A和Application B之间共享它。但是这需要在每个应用程序bin文件夹中有两个程序集副本。如果应用程序A和应用程序B部署在同一台机器上,我想在一个位置更新共享程序集的单个实例,并更新应用程序A和应用程序B.有没有一种方法,应用程序A和应用程序B可以在此程序集的相同位置查看,因为一个使用.NET Core而另一个使用.NET Framework?

c# .net .net-core .net-standard
1个回答
1
投票

史蒂夫用他的评论向我指出了正确的方向。以下是完整的答案和示例。我在.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包包含在Core和Framework Applications中。两个应用程序几乎完全相同。这是代码。

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,Version = 1.0.10765.0,Culture = neutral,PublicKeyToken = null

解析到路径C:... \ SharedLibrary \ SharedAssemblies \ MyLibrary.dll

版本是1.0.10930

按Enter键继续...

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

您可以在this GitHub project上获取所有源代码。

© www.soinside.com 2019 - 2024. All rights reserved.