Rispondo qui ancora ad un altra domanda anch'essa piuttosto frequente:
"...Perchè non posso usare nei miei oggetti di dominio delle collezioni come BindingList, che implementano già IList?"
Bisogna ragionare al contrario. Non a caso sotto sotto c'è proprio una inversione di controllo:
NHibernate non ha bisogno di un oggetto concreto che implementi un'interfaccia IList.
Ha bisogno piuttosto di un oggetto astratto (come IList) in modo che la factory crei a runtime un oggetto concreto da iniettare al parent (dipendente dalla configurazione).
(Secondo Fowler l'Inversione di controllo dovrebbe essere più propriamente chiamata dependency injection proprio per questa azione di "iniettare dipendenze di oggetti collaborators")
Classico esempio:
public class Parent
{
public IList<item> children;
public Parent()
{
children = new List<item>;
}
}
Se facessi io una new di Parent, mi ritrovo una semplice List (cui accedo tramite interfaccia)
Se non faccio io la new, ma la fa la factory per te (nel caso di una load dal database):
parent = session.Load<item>(id)
Internamente verrà fatto qualcosa del genere:
parent.children = new List<item>()
//oppure a seconda della configurazione...
parent.children = new SortedList<item>()
Se children fosse un List<T> (o un BindingList<T>) invece che un IList<T> l'assegnazione non potrebbe avvenire (infatti viene sollevata una CastException).
Se la successiva domanda dovesse allora essere: "perchè non popolare la lista invece che crearla da zero?...."
la mia risposta sarà: perchè si perderà irrimediabilmente il polimorfismo.
Se domani NHibernate facesse uso di una supercollezione SuperCoolList<T> il client non se ne accorgerebbe, e sfrutterebbe le caratteristiche in modo polimorfico.
Devo ringraziare Alessandro Di Noia per avermi dato due ottimi spunti per questi post.