I have a netstandard20 class library and a console application which has no direct reference to that class library. Instead I need to load that library at runtime so that types could be resolved correctly. For now my console application targets net8.0 and I do it the following way:
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
namespace AssemblyResolveTest
{
internal class Program
{
static void Main(string[] args)
{
//if I uncomment this line typeSecondAttempt would be null below
//var typeFirstAttempt = Type.GetType("DataClasses.TestDataClass");
var path = Path.Combine(Directory.GetCurrentDirectory(), "DataClasses.dll");
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
var typeSecondAttempt = Type.GetType("DataClasses.TestDataClass, DataClasses");
}
}
My first problem is - why if I uncomment typeFirstAttempt line typeSecondAttempt becomes null (cannot be resolved)?
My second problem is that now I need to move library load logic to a netstandard20 class library and I cannot use System.Runtime.Loader.AssemblyLoadContext there. There is a nuget but it is working when called only from .NET (but I need to support .NET Framework as well). The only approach I know is AppDomain.CurrentDomain.AssemblyResolve, like that:
using System;
using System.IO;
using System.Reflection;
namespace AssemblyResolveTestClassLibrary
{
public static class AssemblyResolver
{
static AssemblyResolver()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (new AssemblyName(args.Name).Name == "DataClasses")
{
var path = Path.Combine(Directory.GetCurrentDirectory(), "DataClasses.dll");
return Assembly.LoadFile(path);
}
else
return null;
}
public static Type GetTestDataClassType()
{
return Type.GetType("DataClasses.TestDataClass, DataClasses");
}
}
}
But Assembly.LoadFile(path) executes every time I call AssemblyResolver.GetTestDataClassType(). My goal is to load assembly one time - how to achieve that? Maybe some other AppDomain.CurrentDomain function?
Thank you.
UPDATE - clarification about my project real structure (simplified):
Interfaces - netstandard20 library. Let's say it has:
public interface ISampleResult
{
Guid Id { get; }
}
public interface ISampleService
{
ISampleResult GetSampleResult();
}
DataClasses - netstandard20 library, references Interfaces library. Let's say it has:
public class SampleResult(Guid id) : ISampleResult
{
public Guid Id { get; } = id;
}
Server - net8.0 class library that actually performs operations, declared in interfaces. It references Interfaces and DataClasses libraries. Let's say it has:
public class SampleService : ISampleService
{
public ISampleResult GetSampleResult()
{
return new SampleResult(Guid.Empty);
}
}
IPC - netstandard20 library, references Interfaces library and NewtonSoft.Json nuget. It is a library for inter-process communication: plugins (can be net472 or net8.0+, that reference Interfaces library) sends a Func<T> request to be actually executed on a server and get response with result. Requests/responses are sended as JSON. Let's say plugin requests ISampleService.GetSampleResult() - when NewtonSoft.Json tries to deserialize response from server it fails, because IPC knows nothing about DataClasses. Thats why I need to detect such situations and load DataClasses library at runtime (but only once).
Feel free to ask questions if I didn't clarified enough.
var assembly = Assembly.LoadFile(path); var testDataType = assembly.GetType("DataClasses.TestDataClass")?netstandard20library for which I need a working solution serializes/deserializes objects from JSON via NewtonSoft.JSON library. I will add this clarification to my question.