Невозможно привести прозрачный прокси к типу из AppDomain - PullRequest
11 голосов
/ 07 сентября 2010

Я пытаюсь создать объект в домене приложения:

var type = typeof (CompiledTemplate);
var obj = (CompiledTemplate) domain.CreateInstanceAndUnwrap (
    type.Assembly.FullName, type.FullName);

Однако я всегда получаю следующую ошибку:

Невозможно привести прозрачный прокси к типу 'Mono.TextTemplating.CompiledTemplate '.

Я работаю в .NET 4.0, а не в Mono, несмотря на то, что может предложить пространство имен:)

Насколько я знаю, эта ошибкапроисходит, когда .NET считает, что тип и сборка не совпадают в двух доменах.Однако при отладке FullName и Location идентичны.Отличается только свойство Assembly.Codebase - в дочернем AppDomain его расширение почему-то прописано в «DLL».

Я попытался добавить обработчик AssemblyResolve в AppDomain, который использует Assembly.LoadFrom для загрузкиимя файла явно, но расширение CodeBase все еще становится заглавными.Поскольку исходная сборка также была загружена с помощью Assembly.LoadFrom (через Mono.Addins), разница между значениями CodeBase кажется очень странной.

Есть предложения по устранению этой проблемы или обходу этой проблемы?

Ответы [ 4 ]

5 голосов
/ 24 января 2011

Не могли бы вы столкнуться с проблемой контекстов загрузки сборки?(например, см. здесь ). У вас есть тип, который явно находится в контексте загрузки (потому что вы используете typeof(CompiledTemplate)), но вы говорите, что тип во вторичном AD загружен виз контекста ...

Вы проверяли с помощью fuslogvw , чтобы точно определить, какие сборки загружаются?Трассировка fuslog также сообщит вам, загружаются ли сборки в разных контекстах.

1 голос
/ 24 января 2011

Вторая копия сборки действительно загружается в память как есть.

Экземпляр типа во время выполнения специфичен для экземпляра загруженной сборки, поэтому даже если тот же файл DLL загружается во второй раз, типы не считаются совпадающими.

Это типичная проблема, когда «DLLHell» расширяется до «GACAndDLLHell». "GACONLYHeaven" - лучшее место ...:).

То, что имена файлов слегка различаются (расширение .DLL имеет другой регистр) подразумевает, что одна и та же DLL загружается из двух мест (то есть: GAC нечувствителен к регистру / всегда в нижнем регистре для имен файлов IIRC).

Здесь вам нужен абстрактный класс или, предпочтительно, интерфейс.

Если вы не можете вносить изменения в базу кода, я бы, во-первых, убедился, что DLL существует только в 1 месте на диске (или в 0 местах на диске, если он загружается из GAC). Копия библиотеки DLL, которая содержит тип: 'CompiledTemplate' в вашей папке app / bin, будет настоящим виновником ...?

Это новый код или существующий код, который по какой-то причине сейчас не работает?

0 голосов
/ 28 августа 2018

У меня есть приложение WCF с именованными каналами, которое использует архитектуру обратного вызова (дуплекс).

Я получил эту ошибку, потому что мой сервисный интерфейс [ServiceContract] был аннотирован неправильным обратным вызовом.

0 голосов
/ 20 декабря 2010

Возможно, вы можете использовать ключевое слово dynamic вместо приведения его к определенному типу:

var type = typeof (CompiledTemplate);
dynamic obj = domain.CreateInstanceAndUnwrap (
    type.Assembly.FullName, type.FullName);

Это может по крайней мере дать вам обходной путь к проблеме.Конечно, потенциальные недостатки будут заключаться в отсутствии проверки времени компиляции и / или снижении производительности.Однако это может быть незначительным компромиссом в зависимости от вашей ситуации.

...