Проблема отражения в контексте ASP.net - PullRequest
1 голос
/ 29 апреля 2009

У меня есть приложение ASP.net, которое ссылается на внешнюю сборку, которая мне нужна для динамической загрузки и обнаружения любых типов, реализующих известный интерфейс. Проблема, с которой я сталкиваюсь, заключается в том, что отображаемый мной тип не соответствует тому интерфейсу, который работает, и поэтому я не могу его привести.

Пример:

Этот код запускается в приложении ASP.net.

var assembly = Assembly.LoadFile(Path.Combine(HttpRuntime.BinDirectory, "ExternalAssembly.dll"));

var type = assembly.GetExportedTypes().First<Type>(x => x.Name == "AClass"); // AClass implements IAInterface

var reflectedInterface = type.GetInterface(typeof(IAmAInterface).ToString());

if (reflectedInterface != typeof(IAmAInterface))
    throw new Exception("This makes me sad"); // This code gets run

Единственное различие, которое я вижу между отраженным интерфейсом, загруженным из корзины, и интерфейсом, возвращаемым из typeof, заключается в том, что сборка typeof находится в пути к временному ASP.net (C: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ Временные файлы ASP.NET \ root \ 08c43c8b \ 3adac8cf \ assembly \ dl3 \ eb7a4127 \ 0235ea60_a3c8c901 \ ReflectionTest.DLL)

Спасибо, Пол Александр, я изменил код для использования метода Assembly.Load, а не Assembly.LoadFile, который решает проблему.

wwilden: я также пытался извлечь интерфейс в его собственную сборку, и это также решает проблему.

Ответы [ 4 ]

2 голосов
/ 29 апреля 2009

Когда вы используете LoadFile, сборка не загружается в тот же контекст, что и другие ваши сборки во время выполнения, так что типы интерфейса CLR отличаются. Вы можете прочитать больше в Сюзанне Кук Сбой загрузки отладочной сборки .

Если загружаемая сборка уже находится в каталоге Bin - вы можете загрузить ее по имени. Вам не нужно знать точный путь, поскольку папка Bin уже находится в пути проверки сборки.

1 голос
/ 29 апреля 2009

Где определен тип вашего интерфейса? Существует ли он как в отраженной сборке, так и в самом приложении? Тогда у вас фактически есть два разных интерфейса, даже если они имеют одинаковое пространство имен и имя.

Вам нужно извлечь интерфейс из отраженной сборки и поместить его в другую сборку, на которую вы ссылаетесь как из отраженной сборки, так и из вашего приложения. Тогда это должно работать.

0 голосов
/ 29 апреля 2009

В CodeProject есть интересная статья о такой ситуации. Где у вас есть класс, структура которого идентична интерфейсу без реализации самого интерфейса. В статье описывается метод динамического создания классов-оболочек, которые реализуют необходимый интерфейс. Это может быть полезно в вашей ситуации.

0 голосов
/ 29 апреля 2009

Помимо вашей проблемы, если у вас есть много сборок для динамической загрузки, помните, что они будут оставаться в памяти до перезагрузки рабочего процесса ASP.NET. Это может повлиять на производительность вашего сервера.

Вы можете загрузить сборки в отдельном домене приложений (наименьший модуль, который можно выгрузить), загрузить прокси-класс в том домене приложений, на который вы ссылаетесь с удаленным взаимодействием. По завершении вы выгружаете домен приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...