具有多个搜索路径的 .NET Core 应用程序.NET Core application with multiple search paths

.NET Core application with multiple search paths

提问人:Sess 提问时间:11/9/2023 最后编辑:Sess 更新时间:11/9/2023 访问量:15

问:

我正在处理一个复杂的迁移到 .NET Core 6 应用程序,该应用程序具有一组共享程序集,由于我们的部署策略,这些程序集与主应用程序程序集位于不同的路径中。

库是静态链接的,因此遗憾的是,我无法使用或扩展解析过程。我看到提供了添加似乎有效的可能性,但我只设法使用绝对路径 - 这是无稽之谈,因为我不知道目标机器上的实际路径。AssemblyLoadContextAppDomainruntimeconfig.jsonAPP_PATHS

我不能使用相对路径吗?每当我尝试子路径时,我都会收到无法创建运行时的异常。这有什么神奇的语法吗?将程序集放在多个文件夹中不会那么复杂。我觉得自己很傻。

这里有人有想法吗?我不能只是改变部署结构/过程。

谢谢

更新:在仔细订阅 AssemblyLoadContext.Default 并确保仅在静态主函数中发生这种情况,而不是某些静态构造函数干扰后,它就可以工作了。谢谢你的提醒。

.net-core 运行时 程序集加载 net-core runtime .net-6.0 search-path assembly-loading

评论

0赞 Hank 11/9/2023
我不明白为什么你不能使用.程序集在编译时用于验证类型,但如果应用程序文件夹中缺少程序集,则可以在运行时重定向程序集的加载位置。AssemblyLoadContext

答:

0赞 Hank 11/9/2023 #1

我评论的一个例子。我有三个项目:库、库和应用程序。ABC

A.csprojB.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

ClassA在项目中。A

using System.Runtime.CompilerServices;

namespace A
{
    public static class ClassA
    {
        [MethodImpl(MethodImplOptions.NoInlining)]
        public static int Plink()
        {
            return 1;
        }
    }
}

ClassB

using System.Runtime.CompilerServices;

namespace B
{
    public class ClassB
    {
        [MethodImpl(MethodImplOptions.NoInlining)]
        public static int Plonk()
        {
            return 2;
        }
    }
}

C.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>exe</OutputType>
    <TargetFrameworks>net8.0</TargetFrameworks>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\A\A.csproj" Private="false" />
    <ProjectReference Include="..\B\B.csproj" Private="false" />
  </ItemGroup>
</Project>

Program.cs


using System.Runtime.CompilerServices;
using System.Runtime.Loader;

using A;
using B;

namespace C
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            SetupAssemblies();
            Foo();
        }

        private static void SetupAssemblies()
        {
            AssemblyLoadContext.Default.Resolving += Default_Resolving;
        }

        private static System.Reflection.Assembly? Default_Resolving(AssemblyLoadContext arg1, System.Reflection.AssemblyName arg2)
        {
            Console.WriteLine($"Attempting to resolve {arg2}");

            string assemblyPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), $@"..\deps\{arg2.Name}.dll"));
            return AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void Foo()
        {
            Console.WriteLine(ClassA.Plink() + ClassB.Plonk());
        }
    }
}

我按如下方式构建了我的输出

~\Projects\SO\C\BIN\DEBUG
│
├───deps
│       A.dll
│       B.dll
└───net8.0
        C.deps.json
        C.dll
        C.exe
        C.pdb
        C.runtimeconfig.json

节目输出:

尝试解析 A,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null 尝试解析 B,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null

3

评论

0赞 Sess 11/9/2023
奇怪的是,即使在命中 Main-Method 之前,我也收到了一个 FileNotFound 异常
0赞 Sess 11/9/2023
更新:我意识到...我的克星叫做静态构造函数。我不得不重写程序,现在它可以工作了......唉。。。