开发者

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

开发者 https://www.devze.com 2023-04-06 20:01 出处:网络
Let\'s say I have a library Lib.dll, which uses Castle.Windsor to initialize its services. I have a main application App.exe, which loads Lib.dll on runtime using reflection. App.exe does not know th

Let's say I have a library Lib.dll, which uses Castle.Windsor to initialize its services.

I have a main application App.exe, which loads Lib.dll on runtime using reflection. App.exe does not know the location of Lib.dll beforehand, it is only known at runtime.

In this case, when App.exe loads Lib.dll and Lib.dll initialize its services, a System.TypeInitializationException exception is thrown, because Castle.Windsor cannot find the service type.

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 Castl开发者_如何学Pythone.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

Apparently Castle cannot find my service class because it is in Lib.dll that is not located in App.exe's directory. When I copy Lib.dll to App.exe directory, the problem goes away, but having to copy this is not something we want.

So how can my code in Lib.dll tell Castle.Windsor to load the class in the correct location? (in Lib.dll location instead of in App.exe location)


You can try to load the unresolved assemblies within your code by AssemblyResolve event

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.
};


You probably will consider loading the plugin in a separate AppDomain, with a different private path, look at AppDomainSetup. Of course there is a drawback that you neeed a separate app domain for your plugin, but sometimes this is considered a good practice.


You probably can't do it in easy and elegant way if App.exe doesn't provide you Castle Windsor's container instance to configure your services.

If it is not exposed directly, maybe you can access it using Service Locator? Or find it on your own using reflection on App.exe assembly?

The best solution will be if code in App.exe calls specific method in your library (i.e. it can look for particular interface implementation, like IModuleInitializer or something, create an instance of it and call some kind of Initialize method passing container instance to your code).

You could also think about extensibility frameworks like MEF, but that can be a bit overkill and make big influence on App.exe.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号