Загрузка связанных dll
Плюс-минус вменяемое расширение под AC/NC лично у меня редко получается загнать в одну-единственную dll. Хотя бы потому, что ее нормально не протестировать. Так что частенько получается несколько dll, каким-то манером связанные между собой. И вот тут и начинаются танцы
Допустим, есть некая App.Cad.dll, которая собственно и загружается в AC/NC. Она связана с App.View.dll и, к примеру, App.Logic.dll. Если не предпринимать никаких действий, любое обращение к "связанным" dll из-под AC/NC будет вываливать ошибку. Потому как их надо загружать принудительно. Самое простое решение - нарисовать AssemblyResolve в инициализаторе приложения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public class MyPlugin : IExtensionApplication { void IExtensionApplication.Initialize() { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; } void IExtensionApplication.Terminate() { } private Assembly CurrentDomainOnAssemblyResolve(object Sender, ResolveEventArgs Args) { string name = GetAssemblyName(Args); string path = Path.Combine(Path.GetDirectoryName((typeof(MyPlugin).Assembly.Location)), name + ".dll"); if (File.Exists(path)) { Assembly assembly = Assembly.LoadFrom(path); if (assembly.FullName == Args.Name) { return assembly; } } return null; } private string GetAssemblyName(ResolveEventArgs args) { if (args.Name.IndexOf(",") > -1) { return args.Name.Substring(0, args.Name.IndexOf(",")); } else { return args.Name; } } } |
И... Ура, все работает!
До тех пор, пока App.View.dll не окажется связанной с какой-то сторонней библиотекой (тем же самым FontAwesome, к примеру). Вот эта библиотека "второго уровня связанности" через AssemblyResolve почему-то не грузится. Можно, конечно, попытаться в Initialize прописать принудительную загрузку только FontAwesome, но это как-то не комильфо: подобных связей может быть очень много. Ну или в App.Cad.dll прокинуть связь с FontAwesome - но это тоже так себе затея, как мне кажется.
Уж проще в Initialize загнать загрузку всех dll из каталога приложения, благо на C# это делается не в пример легче, чем в лиспе:
1 2 3 4 5 6 7 8 9 10 11 12 13 | private void LoadAllAssemblies() { string name = typeof(MyPlugin).Assembly.Location; foreach (string file in Directory.EnumerateFiles(Path.GetDirectoryName(name), "*.dll") .Where(o => !o.Equals(name, StringComparison.InvariantCultureIgnoreCase))) { try { Assembly.LoadFile(file) } catch { } } } |
Что самое интересное, при таком подходе в NC23.1 некорректно срабатывает LoadFrom, а вот LoadFile - пашет превосходно. Магия...