Заобиколно решение за AppDomains на добавките

Когато работите с модули на плъгини в техните собствени поддиректории, съществува добре известният проблем, че тези модули не успяват да се заредят, след като се опитат да заредят съответните им зависимости от техните поддиректории. Решение е да се заредят добавките в AppDomains, чиито PrivateBinPath са зададени в техния AppDomainSetup обект при инициализация. Това обаче причинява други трудности, свързани с маршалинга/комуникацията между домейни на приложения, особено ако приставките трябва да предоставят някакъв GUI.

Когато аспектите на сигурността имат по-нисък приоритет (некритично помощно приложение, няма сериозни проблеми при сривове, причинени от дефектни плъгини), имах следната идея: При стартиране на приложението трябва да се търсят всички директории на плъгини и нова Трябва да се създаде AppDomain, който има тези директории в своя bin път. След това цялото приложение и неговия GUI се изпълняват в този нов AppDomain, заедно с всички добавки.

При дадените обстоятелства има ли причини да се избегне това решение? Или може би има някакви причини, поради които това решение дори не е осъществимо?


person O. R. Mapper    schedule 06.06.2012    source източник
comment
Мисля, че ако основният ви потребителски интерфейс работи в същия AppDomain като приставката, основният потребителски интерфейс вероятно ще се срине, ако приставката се срине. Използвате ли рамката за добавки или е RYO?   -  person IAbstract    schedule 05.08.2012
comment
@IAbstract: Дори когато се изпълнява в друг AppDomain, сривовете на приставката обикновено не водят до срив на основния потребителски интерфейс? В края на краищата всички изключения, хвърлени в приставката, се подреждат през границите на AppDomain и карат основното приложение да излезе, освен ако не обработвам изключенията. В моя конкретен случай това е RYO - разгледах Addin Framework и прочетох много статии за него, но всички те се отнасяха за доста минималистични интерфейси между основното приложение и добавките, а не за сложните и дълбоко вложени йерархии на обекти, които ще нужда от прехвърляне.   -  person O. R. Mapper    schedule 05.08.2012


Отговори (1)


Като вземем предвид описания от вас сценарий, не знам за проблем, свързан с предложението ви за втори домейн. Можете обаче също така да проучите възможността за справяне с грешките при зареждане на асемблирането в първоначалния домейн, като потърсите сами в поддиректориите на addins и заредите асемблирането от там с помощта на Assembly.LoadFrom.

Пример за възможна настройка за това, при което FindAssemblyByName трябва да се приложи за търсене във всички възможни местоположения:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    // ...
}

static Assembly CurrentDomain_AssemblyResolve(
    object sender, 
    ResolveEventArgs e)
{
    var assemblyName = new AssemblyName(e.Name);

    string assemblyFilePath = FindAssemblyByName(assemblyName);

    if (string.IsNullOrEmpty(assemblyFilePath))
        return null;

    return Assembly.LoadFrom(assemblyFilePath);
}
person João Angelo    schedule 11.08.2012
comment
Ще работи ли това само за управлявани сборки? По-конкретно, когато ръчно намеря асемблиране на приставка в поддиректория, неуправляваните библиотеки в същата поддиректория ще бъдат ли открити автоматично? - person O. R. Mapper; 15.08.2012
comment
Assembly.LoadFrom позволява да бъдат намерени и заредени допълнителни зависимости от този път, тъй като информацията за пътя се поддържа от контекста. Въпреки това, с неуправляеми сглобки в микса, не ми е удобно да ви давам някаква сигурност. - person João Angelo; 15.08.2012
comment
Прочетох повече за това и направих някои тестове. Изглежда наистина, че ще бъдат намерени не само управлявани, но и неуправляеми библиотеки, ако са в същата директория като сборката, заредена с LoadFrom. Въпреки това, четейки в документи, изглежда, че LoadFrom зарежда изключително асемблити в така наречения контекст зареждане от, докато контекстът на зареждане би бил за предпочитане по различни причини. От друга страна, не виждам никакъв начин за зареждане на сборка в този контекст на зареждане от потребителско местоположение. - person O. R. Mapper; 28.08.2012