views:

378

answers:

3

I have a rich client application that uses Castle Windsor. At the moment all the assemblies including the application exe are in the one folder but it all looks rather untidy. I would like to put my dlls inside a subfolder such as "bin" but this prevents Castle from locating types etc when called upon. In fact the app crashes at start up.

Is there a way to tell Castle to look somewhere else for the files?

+1  A: 

That depends on how you are configuring the Windsor.

In case you use Castle.MicroKernel.Registration interface, you should load assemblies manually and then register loaded types in the container.

Yuriy Ostapenko
+1  A: 

Castle doesn't do any assembly loading itself, it just relies on fusion to locate the assembly based on it's default probing behaviour - so this is more a general .Net Framework question.

One way to do what you want is to handle the assembly resolution failure and directing the runtime to where the assembly can be located - one way to achieve this is to override assembly resolve (see msdn for details) and then write some code to locate and load the appropriate assembly from the correct location.

This would obviously allow you to support any kind of directory scheme, not just a binary subdirectory (so you could for instance have a separate directory for plugins).

Bittercoder
A: 

You can use a custom XmlInterpreter to initialize your container with. Create a class that inherits XmlInterpreter and put the following override in that class: This one processes all *.dll.config in the directory of the current executing assembly, which easily could be rewritten to use a recursive file lookup of some kind.

public override void ProcessResource( Castle.Core.Resource.IResource source, Castle.MicroKernel.IConfigurationStore store )
{
    base.ProcessResource( source, store );
    var baseDir = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
    foreach( var extraConfig in Directory.GetFiles( baseDir, "*.dll.config" ) )
    {
     try
     {
      var interpreter = new XmlInterpreter( extraConfig ) { Kernel = Kernel };
      interpreter.ProcessResource( interpreter.Source, store );
     }                      
     catch(ConfigurationErrorsException)
     {
      throw;
     }
     catch( Exception ex )
     {
      throw new InvalidOperationException( "Failed to load configuration: " + extraConfig, ex );
     }
    }
}
Johan Andersson
This code is only for config loading as far as I can tell... it doesn't load any assemblies
Mauricio Scheffer