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

C# 在Startup.cs.net core 2.1中加载程序集,c#,.net,asp.net-core-2.1,C#,.net,Asp.net Core 2.1,我在一个名为nuqkgs的文件夹中有nugget包,在项目启动时,我想将这些包(有dll)加载到项目中,以便在运行时使用 我使用下面的代码来加载它们,调试时我可以看到信息以及找到并打开的dll,但是当应该使用它们时,我得到的错误是找不到dll,并且我可以看到解决方案尝试在bin文件夹中查找它们(它们位于solution/nuqkgs/) 我不想在任何文件中注册包,我只是想能够将一个nugget包放到nuqkgs文件夹中,并自动注册 在core 2.1中有任何想法或任何人这样做过吗 这是我的sta

我在一个名为nuqkgs的文件夹中有nugget包,在项目启动时,我想将这些包(有dll)加载到项目中,以便在运行时使用

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

我不想在任何文件中注册包,我只是想能够将一个nugget包放到nuqkgs文件夹中,并自动注册

在core 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);
 }
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
options.checkApprovered=context=>true;
options.MinimumSameSitePolicy=SameSiteMode.None;
});
IList components=新列表();
foreach(目录.EnumerateFiles(@“C:\Users\myName\source\repos\core2.1test\core2.1test\nuqkgs\”、“*.nupkg”、SearchOption.allDirectory)中的字符串文件)
{
使用(ZipArchive nuget=ZipFile.Open(文件,ZipArchiveMode.Read))
{
foreach(nuget.Entries中的ZipArchiveEntry条目)
{
if(entry.Name.Contains(“.dll”))
{
使用(BinaryReader=newBinaryReader(entry.Open()))
{
Add(Assembly.Load(reader.ReadBytes((int)entry.Length));
}
}
}
}
}
services.AddMvc()
.ConfigureApplicationPartManager(apm=>
{
foreach(组件中的var c)
{
var零件=新装配零件(c);
var des=part.Assembly.Location.ToString();
apm.ApplicationParts.Add(部分);
}
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_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);
                  }
              });
        }
    
    public void配置服务(IServiceCollection服务)
    {
    IList components=新列表();
    foreach(目录.EnumerateFiles(@“C:\Users\userName\source\repos\core2.1test\core2.1test\nuqkgs\”、“*.nupkg”、SearchOption.AllDirectories)中的字符串文件)
    {
    使用(ZipArchive nuget=ZipFile.Open(文件,ZipArchiveMode.Read))
    {
    foreach(nuget.Entries中的ZipArchiveEntry条目)
    {
    if(entry.Name.Contains(“.dll”))
    {
    字符串createPathSource=@“C:\Users\userName\source\repos\core2.1test\core2.1test\nuqkgs\”+entry.Name;
    使用(BinaryReader=newBinaryReader(entry.Open()))
    {
    //第一步
    使用(FileStream fsNew=newfilestream(createPathSource,FileMode.Create,FileAccess.Write))
    {
    写入(reader.ReadBytes((int)entry.Length),0,(int)entry.Length);
    }
    //步骤2
    使用(FileStream readStream=File.Open(createPathSource,FileMode.Open))
    {
    var assembly=AssemblyLoadContext.Default.LoadFromStream(readStream);
    组件。添加(组装);
    }
    }
    }
    }
    }
    }
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddMvc()
    .ConfigureApplicationPartManager(apm=>
    {
    foreach(组件中的var c)
    {
    var零件=新装配零件(c);
    apm.ApplicationParts.Add(部分);
    }
    });
    }
    
    如中所述,
    Assembly.Load(byte[])
    在新的未命名加载上下文中加载程序集,
    AssemblyLoadContext
    (默认加载上下文除外)当前无法解析依赖项。这可能就是你的零件不起作用的原因。尝试使用
    AssemblyLoadContext.Default.LoadFromStream
    而不是
    Assembly.Load(byte[])

    这只是一个非常糟糕的总体计划。我知道你要做什么,但是动态引用只会让你的代码变得非常复杂。首先,您必须始终保持动态,这意味着使用这些动态加载程序集的所有代码也必须通过反射来调用。您的代码将是一堆字符串引用,非常脆弱,所有错误都是运行时错误,而不是编译时错误,它将被用于插件架构ed解决方案,因此所有错误都将在编译时被捕获到,然后再放入文件夹抱歉,有几件事我不明白nugget与此有什么关系?你是打算实时添加dll,还是每次启动一次?正如你在代码中看到的,文件夹中有一块金块,我将它取出,并希望在每个包中注册和使用dll。如果我们将另一个nugget包添加到文件夹中,我们将重新启动应用程序,它将获得registeredNope。根据定义,您正在运行时加载程序集,因此