Last active
February 19, 2026 17:03
-
-
Save sunmeat/740e8ff733bebaaa7590bf4f692b761b to your computer and use it in GitHub Desktop.
DLL runtime
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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}"); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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