Загрузка связанных 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 - пашет превосходно. Магия...

Размещено в .NET, nanoCAD · Метки: , , ,



Комментарии

Есть 1 комментарий к “Загрузка связанных dll”
  1. drz пишет:

    видел жэж??
    https://devkazakov.com/ru/blog/csharp-assemblies/

    Assembly a1 = Assembly.LoadFrom (@"c:\temp1\lib.dll");
    Assembly a2 = Assembly.LoadFrom (@"c:\temp2\lib.dll");
    Console.WriteLine (a1 == a2); // true
    Assembly a1 = Assembly.LoadFile (@"c:\temp1\lib.dll");
    Assembly a2 = Assembly.LoadFile (@"c:\temp2\lib.dll");
    Console.WriteLine (a1 == a2); // false

Поделитесь своим мнением


Я не робот.