Ho 2 implementazioni della stessa interfaccia e voglio usare implementation1 se l'utente è loggato o implementation2 se l'utente non è loggato. Come posso configurarlo con il windsor del castello?Castle windor Aggiunta dipendenza condizionale
risposta
Un modo per risolvere questo sarebbe, registrare il servizio con la chiave e quindi risolvere come necessario.
public interface ISample
{
int Calculate(int a, int b);
}
class SampleB : ISample
{
public int Calculate(int a, int b)
{
return a + b + 10;
}
}
class SampleA : ISample
{
public int Calculate(int a, int b)
{
return a + b;
}
}
La registrazione:
container.Register(Component.For<ISample>().ImplementedBy<SampleA>().Named("SampleA").LifeStyle.Transient);
container.Register(Component.For<ISample>().ImplementedBy<SampleB>().Named("SampleB").LifeStyle.Transient);
// si risolvono quando SampleA necessario.
var sampleA = container.Resolve<ISample>("SampleA");
// Risolve quando è necessario SampleB.
var sampleB = container.Resolve<ISample>("SampleB");
Si potrebbe aggiungere un handler selector, che sarebbe in grado di selezionare tra le implementazioni disponibili a seconda ad esempio se è stato impostato Thread.CurrentPrincipal
(o HttpContext.Current.Request.IsAuthenticated
in ASP.NET/MVC se ricordo correttamente).
Il selettore gestore sarebbe probabilmente guardare un po 'come questo:
public class MyAuthHandlerSelector : IHandlerSelector
{
public bool HasOpinionAbout(string key, Type service)
{
return service == typeof(ITheServiceICareAbout);
}
public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
{
return IsAuthenticated
? FindHandlerForAuthenticatedUser(handlers)
: FindGuestHandler(handlers);
}
bool IsAuthenticated
{
get { return Thread.CurrentPrincipal != null; }
}
// ....
}
L'unico lato negativo di selettori gestore è che non stanno tirato dal contenitore - vale a dire che stanno aggiunti come un'istanza al contenitore al momento della registrazione tempo, in modo che non possano avere le dipendenze iniettate, lo stile di vita gestito, ecc., ma ci sono modi per attenuarlo - dai uno sguardo allo F.T.Windsor se sei interessato a vedere come si può fare.
chiedendo se con la versione 3.0 qualsiasi cosa è cambiata - voglio dire se è ancora necessaria la funzione esterna. – Giedrius
dove chiamereste 'container.Resolve()'? –
Non è possibile che windsor sappia che l'utente è connesso o meno a meno che non si modifichi/estenda la sua implementazione interna. Tra i due può esserci una classe Decider che tiene conto del "log in factor" e fornisce l'implementazione desiderata. –
Windsor * ha * meccanismi per questo (vedi la risposta di mookid), non è necessario modificare la sua implementazione interna. –