Reputation: 113
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);
}
Upvotes: 4
Views: 2824
Reputation: 113
I got it working, the way i use it now:
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);
}
});
}
Upvotes: 0
Reputation: 20076
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[])
.
Upvotes: 2