using System.IO; using System.Reflection; using Azaion.Common.DTO; namespace Azaion.Common.Services; public interface IResourceLoader { Task Load(string fileName, CancellationToken cancellationToken = default); Assembly? LoadAssembly(string asmName); } public class ResourceLoader(AzaionApiClient api, ApiCredentials credentials) : IResourceLoader { private static readonly List EncryptedResources = [ "Azaion.Annotator", "Azaion.Dataset" ]; public Assembly? LoadAssembly(string resourceName) { var assemblyName = resourceName.Split(',').First(); if (EncryptedResources.Contains(assemblyName)) { try { var stream = Load($"{assemblyName}.dll").GetAwaiter().GetResult(); return Assembly.Load(stream.ToArray()); } catch (Exception e) { Console.WriteLine(e); var currentLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!; var dllPath = Path.Combine(currentLocation, "dummy", $"{assemblyName}.dll"); return Assembly.LoadFile(dllPath); } } var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == assemblyName); return loadedAssembly; } public async Task Load(string fileName, CancellationToken cancellationToken = default) { var hardwareService = new HardwareService(); var hardwareInfo = await hardwareService.GetHardware(); var encryptedStream = await api.GetResource(fileName, credentials.Password, hardwareInfo); var key = Security.MakeEncryptionKey(credentials.Email, credentials.Password, hardwareInfo.Hash); var stream = new MemoryStream(); await encryptedStream.DecryptTo(stream, key, cancellationToken); return stream; } }