Credo che alla lunga tutti ci siamo scontrati con la noisitàcomplessitàindigeribilità della gestione della configurazione del container per IoC. In una soluzione corposa, okkio non necessariamente complessa, basta e avanza corposa, è una vera menata.
Si ci sono le fluent interfaces che ci fanno risparmare un sacco di “giornate di inferno”, che altrimenti ci guadagneremmo gestendo la configurazione su file xml, permettendoci di scrivere cose del tipo:
container.Register( Component.For<IWindsorContainer, IServiceProvider>()
    .Instance( container ) );

container.Register( Component.For<ModulesConfigurationSectionHandler>()
    .FactoryMethod( this.container.Kernel, () =>
    {
        var configHandler = ( ModulesConfigurationSectionHandler )ConfigurationManager.GetSection( "modulesConfiguration/installedModules" );
        return configHandler;
    } )
    .LifeStyle.Is( LifestyleType.Singleton ) );
nonostante tutto alla lunga diventano una vera menata, anche perchè la famosa “AllTypes” non è che sia poi così flessibile:
AllTypes.FromAssemblyContaining<Object>()...
Si può fare poco per personalizzare/controllare a fondo quello che succede e se i componenti sono tanti e molto diversificati tra loro resta sempre un piccolo delirio.
Quindi… perchè non pensare di fare una cosa del tipo:
container.RegisterAllTypesIn( GetAssembly.ThatContains<SampleType>() );
e limitarsi a definire sul tipo che vogliamo venga registrato una cosa del tipo:
[Ktulu.Component( typeof( ISampleType ) )]
sealed class SampleType : ISampleType
Ora…
  • funziona, che è la cosa più importante;
  • è veloce e non è che mi faccia poi così schifo che lo sia ;-)
  • le mie orecchie non si lamentano per un nuovo brusio di sottofondo… aka smell, almeno per ora ;-)
  • permette di “tenere insieme” il componente concreto e le informazioni di base sulla sua registrazione, ed anche questo è molto importante perchè quando la solution ne contiene centinaia rischiate di passare la giornata a cercare i pezzi in giro per il solution explorer…;
  • è flessibile quel tanto che basta per gestire le informazioni di base della registrazione di un componente:
    • Contratti;
    • Implementazione concreta;
    • Eventuale Factory;
  • per tutto il resto non c’è Master Card ma un altro extension method che ci permette di personalizzare la configurazione prima che venga definitivamente registrata:

    var componentsToRegister = GetAssembly.ThatContains<ShellViewModel>()
    .ExtractComponentRegistrationsFor( container );

    componentsToRegister.Where( c => c.ServiceType is IMyServiceType ) .ForEach( c => { c.ServiceOverrides( ServiceOverride.ForKey( GetKey.For<ServiceTypeImplementation> ) ); } );

    container.Register( componentsToRegister.ToArray() );
    Minimizzando però la quantità di codice boilerplate da scrivere e riducendo quindi la complessità di manutenzione.
…poi:
  • mancano probabilmente un sacco di cose ma si possono fare/aggiungere all’uopo;
  • Per i puristi c’è da notare che l’unica dipendenza è da un assembly che contiene solo ed esclusivamente la definizione di quell’attributo;
.m