Как использовать Castle.Windsor в сборке, загруженной с использованием отражения - PullRequest
2 голосов
/ 22 сентября 2011

Допустим, у меня есть библиотека Lib.dll, которая использует Castle.Windsor для инициализации своих служб.

У меня есть основное приложение App.exe, которое загружает Lib.dll во время выполнения, используя отражение. App.exe не знает заранее местоположение Lib.dll, это известно только во время выполнения.

В этом случае, когда App.exe загружает Lib.dll и Lib.dll инициализирует свои службы, возникает исключение System.TypeInitializationException, поскольку Castle.Windsor не может найти тип службы.

Castle.MicroKernel.SubSystems.Conversion.ConverterException: Could not convert from 'Lib.TheServiceClass' to System.Type - Maybe type could not be found
   at Castle.MicroKernel.SubSystems.Conversion.TypeNameConverter.PerformConversion(String value, Type targetType) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\MicroKernel\SubSystems\Conversion\TypeNameConverter.cs:line 91
   at Castle.MicroKernel.SubSystems.Conversion.DefaultConversionManager.PerformConversion(String value, Type targetType) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\MicroKernel\SubSystems\Conversion\DefaultConversionManager.cs:line 134
   at Castle.MicroKernel.SubSystems.Conversion.DefaultConversionManager.PerformConversion[TTarget](String value) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\MicroKernel\SubSystems\Conversion\DefaultConversionManager.cs:line 162
   at Castle.Windsor.Installer.DefaultComponentInstaller.SetUpComponents(IConfiguration[] configurations, IWindsorContainer container, IConversionManager converter) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\Windsor\Installer\DefaultComponentInstaller.cs:line 196
   at Castle.Windsor.Installer.DefaultComponentInstaller.SetUp(IWindsorContainer container, IConfigurationStore store) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\Windsor\Installer\DefaultComponentInstaller.cs:line 52
   at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers, DefaultComponentInstaller scope) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\Windsor\WindsorContainer.cs:line 327
   at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers) in e:\OSS.Code\Castle.Windsor\src\Castle.Windsor\Windsor\WindsorContainer.cs:line 674

Видимо Castle не может найти мой класс обслуживания, потому что он находится в Lib.dll, который не находится в каталоге App.exe. Когда я копирую Lib.dll в каталог App.exe, проблема исчезает, но нам не нужно копировать ее.

Так как мой код в Lib.dll может сообщить Castle.Windsor о загрузке класса в правильном месте? (в папке Lib.dll, а не в папке App.exe)

Ответы [ 3 ]

2 голосов
/ 28 сентября 2011

Вы можете попытаться загрузить неразрешенные сборки в своем коде с помощью AssemblyResolve событие

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
     string typeToLoad = args.Name;
     string myPath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
     return Assembly.LoadFile(...); //or return Assembly.GetExecutingAssembly() etc.
};
0 голосов
/ 26 сентября 2011

Вы, вероятно, не сможете сделать это простым и элегантным способом, если App.exe не предоставит вам экземпляр контейнера Castle Windsor для настройки ваших служб.

Если он не отображается напрямую, возможно, вы можете получить доступэто с помощью Service Locator ?Или найти его самостоятельно, используя отражение в сборке App.exe?

Лучшее решение будет, если код в App.exe вызывает конкретный метод в вашей библиотеке (т. Е. Он может искать конкретную реализацию интерфейса, например * 1007).* или что-то еще, создайте его экземпляр и вызовите какой-нибудь Initialize метод, передающий экземпляр контейнера в ваш код).

Вы также можете подумать о каркасах расширяемости, таких как MEF , но этоможет быть немного излишним и оказать большое влияние на App.exe.

0 голосов
/ 22 сентября 2011

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

...