2010-06-28 12 views
15

È considerata una cattiva forma registrare componenti in Windsor senza specificare un'interfaccia? cioèVa bene registrare componenti in Windsor senza specificare un'interfaccia?

container.Register(Component.For<MyClass>().LifeStyle.Transient); 

al contrario di ...

container.Register(Component.For<IMyClass>().ImplementedBy<MyClass>().LifeStyle.Transient); 

ho capito i vantaggi di codifica a un'interfaccia piuttosto che una concreta attuazione però stiamo scoprendo che ora abbiamo un sacco di interfacce molti di loro sono su classi che realisticamente avranno sempre una sola implementazione.

risposta

23

Sì, sarebbe opportuno registrare componenti senza le loro interfacce, ma non per il motivo che si fornisce.

dipendenze calcestruzzo

Può accadere che i componenti dipendono dalle classi concrete. Ad esempio, con i clienti di Entity Framework dovrebbe essere inserito l'ObjectContext. Questa è una classe concreta che deve ancora essere iniettata perché dovrebbe essere condivisa tra tra diversi consumatori.

Così, dato il costruttore di un consumatore come questo:

public FooRepository(FooObjectContext objectContext) 

si avrebbe bisogno di configurare il contenitore come questo:

container.Register(Component.For<FooObjectContext>()); 

I FooRepository richieste senza interfaccia quindi non fa registrazione senso un'interfaccia (anche se ne era disponibile una), ma è comunque necessario registrare la classe concreta perché Windsor può risolvere solo i tipi registrati esplicitamente.

interfacce con una sola implementazione

Poi per quanto riguarda le interfacce con una sola applicazione? Ancora una volta, il consumatore decide i requisiti.

Immaginate che un consumatore ha questo costruttore:

public Ploeh(IBar bar) 

L'unico modo Castello di Windsor sarà in grado di risolvere Ploeh è al momento della registrazione IBar. Anche se Bar è l'unica implementazione di IBar, questo non funzionerà:

container.Register(Component.For<Bar>()); 

Questo non funziona perché IBar si è mai registrato. Il castello Windsor non si preoccupa del fatto che Bar implementi IBar perché non vuole provare a essere intelligente a tuo nome. È necessario dire esplicitamente:

container.Register(Component.For<IBar>().ImplementedBy<Bar>()); 

Questo mappe IBar a Bar.

Registrazione di entrambe le interfacce ei tipi concreti

Allora cosa succede se si vuole essere in grado di risolvere sia il tipo di cemento e l'interfaccia?

Il problema con l'esempio precedente è che ti permetterà di risolvere IBar, ma non Bar.

È possibile utilizzare il metodo di andata, o sovraccarico di multigeneric Per inoltrare le iscrizioni:

container.Register(Component.For<Bar, IBar>().ImplementedBy<Bar>()); 

Ciò consente di risolvere sia Bar and IBar.

+2

un altro buon esempio sarebbe Controller in un'applicazione MVC - non è necessario astrarli. –

+0

Sì, i controller MVC sono un esempio ancora migliore - ero solo impantanato in qualche codice EF, quindi mi è venuto in mente prima :) –

+0

Grazie Mark ma se io sono lo sviluppatore che crea la classe Bar dovrei farlo avere un'interfaccia IBar semplicemente in modo che io possa registrarmi a Windsor tramite l'interfaccia? Perché non registrare semplicemente Bar in Windsor e far sì che Ploeh consumi Bar? –