Фактическая причина была в том, что ваша dll загружалась из разных мест в двух разных доменах приложения. Это заставляет .NET думать, что это разные сборки, что, конечно, означает, что типы разные (даже если у них одинаковое имя класса, пространство имен и т. Д.).
Причина, по которой тест Джеффа не прошел при запуске через инфраструктуру модульного тестирования, заключается в том, что платформы модульного тестирования обычно создают домены приложений с ShadowCopy, установленным в значение "true". Но ваш созданный вручную AppDomain по умолчанию будет ShadowCopy = "false". Это может привести к загрузке DLL-файлов из разных мест, что приводит к хорошему «тип объекта не может быть преобразован в целевой тип». ошибка.
ОБНОВЛЕНИЕ: После дальнейшего тестирования кажется, что база данных различается между двумя доменами приложений. Если они совпадают, то приведенный выше сценарий работает. Если они отличаются, это не так (даже если я подтвердил, что dll загружен в оба AppDomains из одного и того же каталога с помощью windbg) Также, если я включу ShadowCopy = "true" в обоих моих AppDomains, то произойдет сбой с другим сообщением: «System.InvalidCastException: объект должен реализовывать IConvertible».
ОБНОВЛЕНИЕ2: Дальнейшее чтение заставляет меня поверить, что оно связано с Загрузка контекстов . При использовании одного из методов «From» (Assembly.LoadFrom или appDomain.CreateInstanceFromAndUnwrap), если сборка находится в одном из обычных путей загрузки (ApplicationBase или один из путей поиска), она загружается в Default Загрузить контекст. Если сборка там не найдена, она загружается в контекст загрузки. Поэтому, когда оба AppDomains имеют совпадающие ApplicationBase, тогда, даже если мы используем метод «From», они оба загружаются в соответствующий контекст загрузки соответствующего AppDomain по умолчанию. Но если база приложения отличается, то один домен приложения будет иметь сборку в контексте загрузки по умолчанию, а другой - в контексте загрузки из нее.