简体   繁体   中英

Load assembly in Startup.cs .net core 2.1

i have nugget packages in a folder called nuqkgs and on project start up i want to load these packages(there dll's) into the project to use at run time.

i use the following code to load them, and when i debug i can see the info and that the dll's are found and opened, however when they should be used i get the error that the dll can not be found, and i can see that the solution try's to look for them in the bin folder(they are located solution/nuqkgs/)

i do NOT want to register the packages in any file i simply want to be able to drop a nugget package into the nuqkgs folder and it gets registered automaticaly

Any ideas or anyone that has done this in core 2.1?

This i my 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);
 }

As described in the docs for AssemblyLoadContext , Assembly.Load(byte[]) loads the assembly in a new unnamed load context, and AssemblyLoadContext (except the default one) currently cannot resolve dependencies. That's probably why your parts don't work. Try using AssemblyLoadContext.Default.LoadFromStream instead of Assembly.Load(byte[]) .

I got it working, the way i use it now:

  1. Open the nuget foreach DLL and I write the dll to a file on the disk.
  2. Open the file in a memory stream and read it into memory and from there it can be used in my application.

Alternatively to step 2 you could use :

AssemblyLoadContext.Default.LoadFromAssemblyPath(createPathSource);

that way you refer to the dll file when using it in your solution

    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);
              }
          });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM