Выделение объекта .NET, когда класс находится в другом пространстве имен - PullRequest
1 голос
/ 25 октября 2011

У меня проблема с распределением объекта между доменами приложений в .NET Windows Service.

Я создал два приложения, которые маршалируют объект в домене приложения и запускают код через прокси MarshalByRefObject

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

Другой проект более сложный, это служба Windows с несколькими проектами. Основная служба Windows загружает библиотеку, которая выполняет сортировку. Тип класса целевого типа Marshal определен в другой библиотеке, поэтому я использую полное имя пространства имен / класса.

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

Не удалось загрузить CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler из сборки ProductNameService , где имя продукта является основным классом службы Windows.

Код:

AppDomain compilerDomain = null;
AppDomainSetup compilerDomainSetup;
CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler scriptCompiler;

...

// Setup a seperate AppDomain 
compilerDomainSetup = new AppDomainSetup();
exeAssembly = Assembly.GetEntryAssembly().FullName;
compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory;

compilerDomainSetup.DisallowBindingRedirects = false;
compilerDomainSetup.DisallowCodeDownload = true;
compilerDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
compilerDomain = AppDomain.CreateDomain("LiveLinkCSScriptDomain", null, compilerDomainSetup);

// Create an instance of the MarshalByRefScriptCompiler in the other AppDomain
scriptCompiler = (CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler)compilerDomain.CreateInstanceAndUnwrap(exeAssembly, typeof(CompanyName.ProductGroup.BusinessObjects.ProductName.MarshalByRefScriptCompiler).FullName);

Я провел исследование этого исключения, и почти все, что я обнаружил, говорит о том, что это проблема с версионированием DLL, однако мои DLL не находятся в GAC, и другие версии не установлены. Я делаю чистую сборку и устанавливаю сервис с помощью installutil.

Я использовал документацию MSDN в качестве руководства для создания кода, выполняющего маршаллинг

Мне интересно, есть ли проблема с загрузкой MarshalByRefScriptCompiler, потому что тип находится в другой библиотеке. Я могу создать MarshalByRefScriptCompiler в простом приложении winforms, но я получаю исключение в своей службе Windows.

Буду признателен за любые советы или понимание!

Ответы [ 2 ]

2 голосов
/ 25 октября 2011

Я должен быть в состоянии помочь вам.Недавно я провел много часов ( Как передать ссылки в качестве параметров метода через домены приложений? ), работая над различными проблемами маршалинга между доменами.Моим первым предложением было бы попробовать использовать CreateInstanceFromAndUnwrap вместо CreateInstanceAndUnwrap .

Я также немного настороженно отношусь к этой строке:

compilerDomainSetup.ApplicationBase = System.Environment.CurrentDirectory;

Как создается ваш оригинальный AppDomain?Вы размещены в IIS, и в этом случае ваш первоначальный домен приложений будет использовать ShadowCopy?Все библиотеки включены в одну папку?

РЕДАКТИРОВАТЬ:

Для суммирования вы можете использовать CreateInstanceAndUnwrap , если установлен compilerDomainSetup.ApplicationBase в каталог, содержащий вашу dll, и вы передаете правильный первый параметр (например, typeof (MarshalByRefScriptCompiler) .Assembly.FullName).

Или вы можете использовать CreateInstanceFromAndUnwrap и просто передать его в расположение(например, typeof (MarshalByRefScriptCompiler). Assembly.Location) содержащей сборки в качестве первого параметра.

1 голос
/ 25 октября 2011

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

...