Wednesday, July 27, 2011

Как правильно подключить обработчик AssemblyResolve в WinForms

Возник интересный вопрос – в какой момент правильнее подключить AssemblyResolve, который, как известно, позволяет подложить нужные dll, если система сама их не нашла.
Вариант 1 – делаем в конструкторе основной формы
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            AppDomain.CurrentDomain.AssemblyResolve +=
                        new ResolveEventHandler(CurrentDomain_AssemblyResolve);
Этот вариант будет работать только в том случае, если форма не использует искомые dll для UI, т.е. конструктор успеет вызваться. Для подключения таким образом UI-компонентов этот вариант не работает.
Вариант 2 – в методе Main
Этот вариант работает, если нужные dll не должны сразу загрузиться в домент. Даже если главная форма использует dll для построения UI, то это будет работать. Если же dll нужны для создания Application, то и этот вариант не сработает.
Вариант 3 – самый надежный, статический конструктор Program
Создаем статический конструктор для основного класса.
    static class Program
    {
        static Program()
        {
            AppDomain.CurrentDomain.AssemblyResolve +=
                 new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            Application.SetUnhandledExceptionMode(
                 UnhandledExceptionMode.CatchException);
        }
Теперь обработчик будет гарантированно создан.