Вот основная проблема: у меня есть приложение .NET, которое использует COM-взаимодействие в отдельном домене приложений. Кажется, что COM-компонент загружает сборки обратно в домен по умолчанию, а не в домен приложений, из которого вызывается COM-компонент.
Что я хочу знать: это ожидаемое поведение, или я делаю что-то не так, чтобы эти связанные с COM сборки загружались в неправильный домен приложения? Более подробное описание ситуации смотрите ниже ...
Приложение состоит из 3 сборок:
- основной EXE, точка входа в приложение.
- common.dll, содержащая только интерфейс IController (в стиле IPlugin)
- controller.dll, содержащий класс Controller, который реализует IController и MarshalByRefObject. Этот класс выполняет всю работу и использует взаимодействие COM для взаимодействия с другим приложением.
Соответствующая часть основного EXE выглядит следующим образом:
AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);
Common.dll содержит только 2 вещи:
public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
ControllerRunResult Run();
}
И контроллер.dll содержит этот класс (который также вызывает взаимодействие COM):
public class Controller: IController, MarshalByRefObject
При первом запуске приложения Assembly.GetAssemblies () выглядит так, как ожидается, при этом common.dll загружается в оба AppDomains, а controller.dll загружается только в домен контроллера. Однако после вызова c.Run () я вижу, что сборки, связанные с компонентами взаимодействия COM, были загружены в AppDomain по умолчанию, а НЕ в AppDomain, из которого происходит COM-взаимодействие.
Почему это может происходить?
А если вам интересно, вот немного предыстории:
Первоначально это было приложение 1 AppDomain. COM-интерфейс, с которым он взаимодействует, является серверным API, который не стабилен в течение длительного периода использования. Когда COMException (без полезной диагностической информации относительно его причины) происходит из COM-компонента, все приложение должно быть перезапущено, прежде чем COM-соединение снова заработает. Простое повторное подключение к серверу приложений COM снова приводит к немедленным исключениям COM. Чтобы справиться с этим, я попытался переместить компонент взаимодействия COM в отдельный AppDomain, чтобы при возникновении таинственных исключений COMException я мог выгрузить AppDomain, в котором он возник, создать новый и начать заново, и все это без необходимости перезапуска приложения , Так или иначе, это была теория ...