1

I created a WebApi project and configured Castle Windsor as DI container.

When I deploy my WebApi on my WebServer, everything is working fine until I restart the web server (I'm using IIS) by clicking on the restart button or by executing the iisreset command. After that, I always have the following error:

No component for supporting the service XXX.ICategoryDomainService was found

When running my project in debug mode inside Visual Studio, this problem seems to happen randomly. But each time I do a full Clean/Rebuild, it's then working at least once. Stopping/Starting the project many times (always inside Visual Studio) brings the problem back. When the exception raised, I inspected the state of the Container and everything seems to be ok

Castle Windsor Configuration

Update:

Ok, I finally managed to find where the problem was (but I do not have a proper solution for now).
I'm doing a registration in a Framework dll that scans all types of my current project and tries then to registered automatically some of these types...

In a Framework Library:

IEnumerable<IInstaller> installers = this.Container.ResolveAll<IInstaller>();
foreach (IInstaller installer in installers)
{
    installer.Install(this.Container);
}

This is how IInstaller is registered:

this.Container.Register(Classes
    .From(ApplicationDomain.Current.ConcreteClasses)
    .BasedOn<IInstaller>()
    .WithServiceAllInterfaces()
    .LifestylePerWebRequest());

A small extensions method (always in Framework)

public static void RegisterAllServices(this IWindsorContainer container, 
    IEnumerable<Type> types)
{
    container.Register(Classes
        .From(types)
        .BasedOn<IService>()
        .WithServiceAllInterfaces()
        .LifestyleTransient());
}

An installer in my project

public class BusinessInstaller : IInstaller
{
    public void Install(IWindsorContainer container)
    {
        Type[] types = typeof(BusinessInstaller).Assembly.GetTypes();
        container.RegisterAllServices(types);
    }
}

It's very weired, but this is what I can observe: The extensions method RegisterAllServices is only called when I do a full rebuild. After that, in debug mode, I can see that the debugger just steps over an never get into this method BUT the types are registered anyway (but probably in a wrong way, because Windsor is not able to resolve them!).

The temporary fix is to register all my classes in the BusinessInstaller. Then it works... but it's not optimal, it would be better if everything could be automatically registered...

Bidou
  • 7,378
  • 9
  • 47
  • 70
  • How does your registration look like? And where did coupled castle with `IDependecyResolver`? – Old Fox Jul 19 '15 at 16:46
  • I don't see any special thing. However I ask my self if there is way which `Container.Current` could be reinitialized.... In my previous job I was the one who configure castle with the `WebApi`, I believe that I'm missing something... I need to find my POC, when I find it I'll upload it... One more thing, I think you should upload the registration of `ICategoryDomainService`. – Old Fox Jul 20 '15 at 18:42
  • Your Container class is relying on the static constructor to initialise the WindsorContainer. In my experience this is fraught when running in ASP.NET. Your code should guarantee that the Container is instantiated AND configured EVERY TIME Application_Start() is called. Also, why split the initialisation of the container between Container() static constructor and ContainerConfiguration.Configure()? – Phil Degenhardt Jul 21 '15 at 00:27
  • I removed the initiialization from the static constructor and put it in the property instead (with a null check on `SingletonContainer`) but it didn't help. The reason for separating those two, is that my `Container` is quite low level (it is somewhere hidden in a Framework library) and I don't want a reference on the whole WebApi stuff like `IDependencyResolver` or `ApiControllerInstaller` – Bidou Jul 21 '15 at 05:10

1 Answers1

1

I think your problem lies in line ApplicationDomain.Current.ConcreteClasses

In brief taking types from Application Domain is not reliable if assemblies are refenced but not used in the code. Therefor fix will be type explicitly reference your assembly containing the installer in your boostrap code like:

var t = typeof(BusinessInstaller).Assembly

See this post for similar issue.

Community
  • 1
  • 1
  • Holy crap! I searched so many hours what the problem was... I dont understand why an explicit exception is not raised... Thank you! – Bidou Jul 30 '15 at 16:34