Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active February 19, 2026 17:03
Show Gist options
  • Select an option

  • Save sunmeat/740e8ff733bebaaa7590bf4f692b761b to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/740e8ff733bebaaa7590bf4f692b761b to your computer and use it in GitHub Desktop.
DLL runtime
// https://learn.microsoft.com/uk-ua/dotnet/api/system.runtime.loader.assemblyloadcontext?view=net-9.0
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;
using System.Text;
namespace UseDll
{
public class Person
{
public string? Name { get; set; }
public int Age { get; set; }
public string? Address { get; set; }
public string? Email { get; set; }
public DateTime BirthDate { get; set; }
public override string ToString()
{
var formattedString = new StringBuilder();
formattedString.AppendLine($"ім'я: {Name ?? "немає даних"}");
formattedString.AppendLine($"вік: {Age}");
formattedString.AppendLine($"дата народження: {BirthDate:dd MMMM yyyy} року");
if (!string.IsNullOrEmpty(Address))
{
formattedString.AppendLine($"адреса: {Address}");
}
if (!string.IsNullOrEmpty(Email))
{
formattedString.AppendLine($"електронна пошта: {Email}");
}
return formattedString.ToString();
}
}
internal class Program
{
static void Main()
{
Console.OutputEncoding = Encoding.UTF8;
// підключаємо бібліотеку динамічно, без імпорту та залежностей
var filePath = @"C:\Users\Alex\Desktop\ClassLibrary1\bin\Debug\net9.0\ClassLibrary1.dll";
var assembly = LoadAssembly(filePath);
if (assembly == null) return;
Console.WriteLine("бібліотека завантажена успішно.");
// отримуємо тип FileFacade у рантаймі
var type = assembly.GetType("FileFacade");
if (type == null)
{
Console.WriteLine("не вдалося знайти тип FileFacade.");
return;
}
// виводимо методи типу FileFacade для перевірки
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
Console.WriteLine("методи FileFacade:");
foreach (var method in methods)
{
Console.WriteLine($"- {method.Name}");
}
// створюємо рефлексивно екземпляр FileFacade
object? facade = Activator.CreateInstance(type);
if (facade == null)
{
Console.WriteLine("не вдалося створити екземпляр FileFacade.");
return;
}
// об'єкт для запису
var person = new Person
{
Name = "Олександр",
Age = 35,
Address = "вул. Джеффрі Ріхтера, 123",
Email = "sunmeatrich@gmail.com",
BirthDate = new DateTime(1989, 3, 10)
};
// текстовий файл буде у папці з проєктом, поруч із виконуваним файлом
string txtFilePath = "person.txt";
if (!File.Exists(txtFilePath))
{
File.Create(txtFilePath).Close();
Console.WriteLine("файл створено.");
}
InvokeWriteToFile(facade, txtFilePath, person);
OpenFileForUser(txtFilePath);
// відключаємо (вивантажуємо) бібліотеку
UnloadAssembly(filePath);
}
static Assembly LoadAssembly(string path)
{
try
{
// контекст збірок керує завантаженням, зберіганням і вивантаженням збірок у додатку, ізолюючи їх одна від одної
var context = new AssemblyLoadContext("MyAssemblyContext", isCollectible: true); // isCollectible - збирач сміття звільнить пам'ять після виклику UnloadAssembly
return context.LoadFromAssemblyPath(path);
}
catch (Exception ex)
{
Console.WriteLine($"помилка завантаження бібліотеки: {ex.Message}");
return null;
}
}
static void UnloadAssembly(string path)
{
try
{
var context = AssemblyLoadContext.All.FirstOrDefault(c => c.IsCollectible);
if (context != null)
{
Console.WriteLine($"вивантажуємо бібліотеку: {path}");
context.Unload();
}
else
{
Console.WriteLine("не вдалося знайти контекст для вивантаження збірки.");
}
}
catch (Exception ex)
{
Console.WriteLine($"помилка вивантаження бібліотеки: {ex.Message}");
}
}
static void InvokeWriteToFile(object facade, string filePath, object data)
{
var writeMethod = facade.GetType().GetMethod("WriteToFile", BindingFlags.Public | BindingFlags.Instance);
if (writeMethod != null && writeMethod.ContainsGenericParameters)
{
var genericType = data.GetType(); // тип, який передається в data (наприклад, Person)
var genericWriteMethod = writeMethod.MakeGenericMethod(genericType);
try
{
Console.WriteLine("виклик методу WriteToFile...");
genericWriteMethod.Invoke(facade, [filePath, data, "text"]);
Console.WriteLine("об'єкт записано у файл.");
}
catch (TargetInvocationException ex)
{
Console.WriteLine($"помилка при записі у файл: {ex.InnerException?.Message ?? ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"помилка при записі у файл: {ex.Message}");
}
}
else
{
Console.WriteLine("метод WriteToFile не знайдено або не є узагальненим.");
}
}
static void OpenFileForUser(string filePath)
{
try
{
string command = string.Empty;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
command = $"start {filePath}";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
command = $"xdg-open {filePath}";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
command = $"open {filePath}";
}
else
{
Console.WriteLine("невідома операційна система.");
return;
}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/C " + command,
CreateNoWindow = true,
UseShellExecute = false
});
Console.WriteLine($"файл {filePath} відкрито для користувача.");
}
catch (Exception ex)
{
Console.WriteLine($"помилка при відкритті файлу: {ex.Message}");
}
}
}
}
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
namespace UseDll
{
internal class Program
{
static void Main()
{
Console.OutputEncoding = Encoding.UTF8;
// підключаємо бібліотеку динамічно, без імпорту та залежностей
var path = @"C:\Users\Alex\Desktop\P45Library\bin\Debug\net10.0\P45Library.dll";
var context = new AssemblyLoadContext("MyContext", isCollectible: true);
var assembly = context.LoadFromAssemblyPath(path); // !!!!!!!!!!!!!!!!
if (assembly == null) Console.WriteLine("OOPS!");
Console.WriteLine("бібліотека завантажена успішно.");
var type = assembly.GetType("P45Library.Cat");
if (type == null)
{
Console.WriteLine("не вдалося знайти тип Cat.");
return;
}
// виводимо методи типу FileFacade для перевірки
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
Console.WriteLine("методи Cat:");
foreach (var method in methods)
{
Console.WriteLine($"- {method.Name}");
}
// створюємо рефлексивно екземпляр Cat
object? cat = Activator.CreateInstance(type);
// Cat cat = new Cat();
var meowMethod = type.GetMethod("Meow",
BindingFlags.Public | BindingFlags.Instance);
// викликаємо метод
meowMethod.Invoke(cat, null); // null — бо метод без параметрів
meowMethod.Invoke(cat, null);
meowMethod.Invoke(cat, null);
meowMethod.Invoke(cat, null);
context.Unload(); // !!!!!!!!!!!!!!!!
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment