加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 22:53:09 所属栏目:百科 来源:网络整理
导读:我有在.NET Core 2.1和.NET Framework 4.7.1中开发的应用程序B中开发的应用程序A.它们具有使用.NET Standard 2.0开发的共享库/程序集.这很好用,我可以编译这个库的单个实例并在Application A和Application B之间共享它.但是这需要在每个应用程序bin文件夹中
我有在.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?

解决方法

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

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

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:…SharedLibrarySharedAssembliesMyLibrary.dll

The version is 1.0.10930

Press Enter key to continue…

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

你可以在this GitHub project获得所有的源代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读