簡體   English   中英

如何在使用反射加載的裝配體中使用Castle.Windsor

[英]How to use Castle.Windsor in an assembly loaded using reflection

假設我有一個庫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無法找到我的服務類,因為它位於App.exe目錄中的Lib.dll中。 當我將Lib.dll復制到App.exe目錄時,問題消失了,但是不必復制它是我們想要的。

那么,我在Lib.dll中的代碼如何告訴Castle.Windsor在正確的位置加載該類? (在Lib.dll位置而不是App.exe位置)

您可以嘗試通過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.
};

您可能會考慮將插件加載到具有不同私有路徑的單獨AppDomain中,請參閱AppDomainSetup 當然,有一個缺點是您需要為插件選擇一個單獨的應用程序域,但是有時這被認為是一種好習慣。

如果App.exe沒有為您提供Castle Windsor的容器實例來配置您的服務,則可能無法輕松,優雅地完成此操作。

如果它不是直接暴露的,也許您可​​以使用Service Locator訪問它? 還是使用對App.exe程序集的反射自行找到它?

最好的解決方案是App.exe中的代碼是否在您的庫中調用特定方法(即,它可以查找特定的接口實現,例如IModuleInitializer或其他東西,創建它的實例,然后調用某種Initialize方法,將容器實例傳遞給您的代碼)。

您還可以考慮像MEF這樣的可擴展性框架,但這可能有點過大,並且會對App.exe產生重大影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM