Поймать исключение в AddInToken.Activate<T>()
Я использую MAF и у меня проблема с активацией надстройки. Позвольте мне объяснить мой план.
Сначала я создаю дополнительный AppDomain, затем пытаюсь активировать надстройку:
MyAddIn = Token.Activate<AddInHostView>(domain);
Мой AddIn очень прост и ссылается только на одну вспомогательную сборку. Если эта вспомогательная сборка находится в каталоге AddIn, все вещи работают как шарм.
AddIns
- MyDemoAddIn.dll
- Helpers.dll
Если я удаляю Helpers.dll весь сбой приложения:
Первое случайное исключение типа "System.IO.FileNotFoundException" произошло в MyDemoAddIn.DLL "PresentationHost.exe" (управляемый (v4.0.30319)): загружено "C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources". \v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll'Первое случайное исключение типа'System.Reflection.TargetInvocationException'произошло в mscorlib.dll Первое случайное исключение типа'System.Reflection.TargetInvocationException'произошло в System.AddIn.dll Первое случайное исключение типа "System.Reflection.TargetInvocationException" произошло в System.AddIn.dll
Я проверил все вещи с обработкой исключений. Я не могу поймать исключение из Host, AddInView или моего созданного AppDomain:-(
У кого-нибудь есть идея?
2 ответа
Ответ проще, чем вы думаете... Проблема была в методе Finalizer () из AddInView.dll, который является промежуточным слоем MAF. Вот мое решение.
Демо (Хост)
try
{
MyAddIn = Token.Activate<AddInHostView>(domain);
}
catch (Exception ex)
{
try
{
AppDomain.Unload(domain);
domain = null;
}
catch (ThreadAbortException threadAbortException)
{
//ToDo: Logging
}
catch (CannotUnloadAppDomainException cannotUnloadAppDomainException)
{
//ToDo: Logging
}
catch (Exception exception)
{
//ToDo: Logging
}
}
AddInView
[AddInBase]
public class AddInView : UserControl
{
//Necessary constructor to handle the exception.
//Normal constructor is not called when an error occurs at startup!!!
static AddInView()
{
AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;
}
//Normal constructor
public AddInView()
{
//Do other things...
//e.g. Dispatcher.UnhandledException += Dispatcher_UnhandledException;
}
static void CurrentDomain_DomainUnload(object sender, EventArgs e)
{
//To cleanup and stuff
}
}
Теперь, если происходит ошибка (Activate<>), обработчик исключений перехватывает ошибку (FileNotFound Helpers.dll не найден) и выгружает весь AppDomain без сбоя основного AppDomain:-)
Ваш плагин не может работать без Helpers.dll. Поскольку он работает через границы AppDomain, надстройке требуется собственный набор DLL для загрузки в собственный AppDomain.
Если вам не нужна перекрестная функциональность AppDomain, вы можете использовать Token.Activate<AddInHostView>(AppDomain.CurrentDomain)
загрузить его, если в вашем хост-проекте есть ссылка на helpers.dll.