在Startup.cs .net core 2.1中加载程序集

时间:2018-07-09 12:54:22

标签: c# .net asp.net-core-2.1

我在名为nuqkgs的文件夹中有块状软件包,在项目启动时,我想将这些软件包(存在dll)加载到项目中以在运行时使用。

我使用以下代码加载它们,并且当我调试时我可以看到信息,并且找到并打开了dll,但是当应使用它们时,我得到了找不到该dll的错误,并且我可以看到该解决方案尝试在bin文件夹中查找它们(它们位于solution / nuqkgs /)

我不想将软件包注册到任何文件中,我只是希望能够将一个金块软件包放入nuqkgs文件夹中,并且它会自动注册

在2.1核心中有任何想法或任何想法吗?

这是我的startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        IList<Assembly> components = new List<Assembly>();
        foreach (string file in Directory.EnumerateFiles(@"C:\Users\myName\source\repos\core2.1test\core2.1test\nuqkgs\", "*.nupkg", SearchOption.AllDirectories))
        {
            using (ZipArchive nuget = ZipFile.Open(file, ZipArchiveMode.Read))
            {
                foreach (ZipArchiveEntry entry in nuget.Entries)
                {
                    if (entry.Name.Contains(".dll"))
                    {
                        using (BinaryReader reader = new BinaryReader(entry.Open()))
                        {
                            components.Add(Assembly.Load(reader.ReadBytes((int)entry.Length)));
                        }
                    }
                }
            }
        }

        services.AddMvc()
          .ConfigureApplicationPartManager(apm =>
          {
              foreach (var c in components)
              {
                  var part = new AssemblyPart(c);
                  var des = part.Assembly.Location.ToString();
                  apm.ApplicationParts.Add(part);
              }
          }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 }

2 个答案:

答案 0 :(得分:1)

docs for AssemblyLoadContext中所述,Assembly.Load(byte[])在新的未命名的加载上下文中加载程序集,而AssemblyLoadContext(默认值除外)当前无法解析依赖关系。这可能就是为什么您的零件不起作用的原因。尝试使用AssemblyLoadContext.Default.LoadFromStream代替Assembly.Load(byte[])

答案 1 :(得分:0)

我可以使用它,现在可以使用它的方式:

  1. 打开nuget foreach DLL,然后将dll写入磁盘上的文件中。
  2. 在内存流中打开文件并将其读入内存,然后可以在我的应用程序中使用它。

第二步,您也可以使用:

AssemblyLoadContext.Default.LoadFromAssemblyPath(createPathSource);

以这种方式在解决方案中使用dll文件时引用该文件

    public void ConfigureServices(IServiceCollection services)
    {
        IList<Assembly> components = new List<Assembly>();

        foreach (string file in Directory.EnumerateFiles(@"C:\Users\userName\source\repos\core2.1test\core2.1test\nuqkgs\", "*.nupkg", SearchOption.AllDirectories))
        {
            using (ZipArchive nuget = ZipFile.Open(file, ZipArchiveMode.Read))
            {
                foreach (ZipArchiveEntry entry in nuget.Entries)
                {
                    if (entry.Name.Contains(".dll"))
                    {
                        string createPathSource = @"C:\Users\userName\source\repos\core2.1test\core2.1test\nuqkgs\"+ entry.Name;

                        using (BinaryReader reader = new BinaryReader(entry.Open()))
                        {
                            // Step 1
                            using (FileStream fsNew = new FileStream(createPathSource, FileMode.Create, FileAccess.Write))
                            {
                                fsNew.Write(reader.ReadBytes((int)entry.Length), 0, (int)entry.Length);
                            }

                            // Step 2
                            using (FileStream readStream = File.Open(createPathSource, FileMode.Open))
                            {
                                var assempbly = AssemblyLoadContext.Default.LoadFromStream(readStream);
                                components.Add(assempbly);
                            }
                        }
                    }
                }
            }
        }
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddMvc()
          .ConfigureApplicationPartManager(apm =>
          {
              foreach (var c in components)
              {
                  var part = new AssemblyPart(c);
                  apm.ApplicationParts.Add(part);
              }
          });
    }