Given an assembly containing components, most of them will have similar configuration requirements. A simple assembly scanning statement usually applies to 90% of them:
Assembly componentsAssembly = // ... var builder = new ContainerBuilder(); builder.RegisterAssemblyTypes(componentsAssembly) .AsImplementedInterfaces();
Now, the annoying thing is - what if one of those components needs to be scoped per-HTTP-request?
In Autofac 2.1, you could exclude it explicitly and then perform configuration separately:
builder.RegisterAssemblyTypes(componentsAssembly) .AsImplementedInterfaces() .Except<LocalCache>(); builder.RegisterType<LocalCache>() .As<ICache>() .HttpRequestScoped();
I wouldn’t say the repetition here is too bad, but over a larger assembly the separation between the
Except() clause and the subsequent registration makes the code harder to follow and thus maintain.
Autofac’s scanning feature is new in version 2, and is slowly evolving towards a minimal syntax. In the latest release, version 2.2, the configuration of an excepted component can be done in-place:
builder.RegisterAssemblyTypes(componentsAssembly) .AsImplementedInterfaces() .Except<LocalCache>(cache => cache.As<ICache>() .HttpRequestScoped(); );
The configuration for the excepted component doesn’t inherit any of the configuration from the outer scanning operation, hence it is necessary to specify the services it will provide despite the
AsImplementedInterfaces() clause in the scanning statement. While I think it would be more concise to specify only the differences between the explicitly-configured component and the rest of the scanning operation, override rules tend to bring a lot of subtle complexities with them and so they’re avoided here.