Что я делаю в таких случаях, я объявляю класс 'initial initialization', который распознается вызывающей сборкой (выбирайте любое соглашение, которое вам нравится: предварительно определенное имя, украшенным настраиваемым атрибутом [AssemblyInitializer]
, реализующим интерфейс, все, что работает для вас). Затем сборка, загружающая другую, ищет этот класс «инициализатор сборки» и вызывает его статический конструктор (или создает его, опять же, что сработает для вас).
Немного больше объяснений, почему я предпочитаю этот способ: в таких случаях загружаемая сборка обычно должна самостоятельно регистрировать некоторые типы в реестре общего типа (например, контейнер IoC), регистрировать некоторые обработчики событий , или выполнить любую другую загрузку, типичную для надстроек или других модульных архитектур. Наличие последовательного подхода «инициализатор сборки» дает такую централизованную глобальную возможность вызывать такие загрузчики.
Хорошая идея - hook-up into the assembly resolution process и вызывать «инициализаторы сборки» из центрального, прозрачного места. Однако вам необходимо опустить системные сборки и не забывать обрабатывать уже загруженные сборки после установки механизма инициализации.