Poiché l'implementazione IoC/DI in MVC 3 è molto probabilmente nella sua forma finale nell'RC, sto cercando un'implementazione aggiornata di DependencyResolver, IControllerActivator e IViewPageActivator utilizzando Caste Windsor. Ci sono degli esempi là fuori che sono stati aggiornati per MVC 3 RC?Castle Windsor Dependency Resolver per MVC 3
EDIT # 1 implementazione di una dipendenza risolutore Windsor è davvero banale, ma c'è ancora qualcosa che manca. Contrariamente all'esempio Ninject di Jeff Putz (sotto), sembra che non sia così semplice con Windsor. Dopo aver impostato il resolver di dipendenza in questo modo,
DependencyResolver.SetResolver(new WindsorDependencyResolver(container));
Windsor genera ComponentNotFoundException. Devo fornire implementazioni per IControllerFactory e IControllerActivator. Poiché la DefaultControllerFactory è DependencyResolver consapevole, questo può essere risolto come segue:
Component.For<IControllerFactory >().ImplementedBy<DefaultControllerFactory>()
Component.For<IControllerActivator >().ImplementedBy<WindsorControllerActivator>(),
WindsorControllerActivator è banale pure. Tuttavia, questo porta a un'altra ComponentNotFoundException per IViewPageActivator.
Questo mi porta a credere che mi manchi qualcosa. Non c'è modo che questo dovrebbe essere più complicato di un'implementazione di un controller factory e chiamare ControllerBuilder.Current.SetControllerFactory MVC 2.0-style.
EDIT # 2 ho perso dettaglio sottile ma importante che il risolutore di dipendenza deve restituire null quando un servizio non può essere trovato. L'implementazione è la seguente:
public class WindsorDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer container;
public WindsorDependencyResolver(IWindsorContainer container)
{
this.container = container;
}
public object GetService(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.ResolveAll(serviceType).Cast<object>() : new object[]{};
}
}
EDIT # 3
Rispondendo a una domanda nei commenti. Se non trovate che è necessario il proprio IControllerActivator, ecco una semplice implementazione per Windsor:
public class WindsorControllerActivator : IControllerActivator
{
private readonly IWindsorContainer container;
public WindsorControllerActivator(IWindsorContainer container)
{
this.container = container;
}
public IController Create(RequestContext requestContext, Type controllerType)
{
return (IController)container.GetService(controllerType);
}
}
}
Ancora una volta, questo è NON necessario per ottenere base DI lavorando con Windsor e il resolver MVC3 dipendenze .
EDIT # 4 Sulla base di alcuni ulteriori ricerche e valutazioni, sembra che un'implementazione del controller fabbrica tradizionale è l'approccio migliore per Windsor e MVC3. La preoccupazione è che l'interfaccia IDependencyResolver manchi di un metodo di rilascio, che potrebbe causare perdite di memoria con Windsor che non dispone dei suoi componenti. Probabilmente questo non sarà un problema se tutte le tue dipendenze verranno risolte con il ciclo di vita di PerWebRequest, ma è comunque meglio non rischiare. Ecco una implementazione di base di una fabbrica di controller Windsor per MVC3.
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;
public WindsorControllerFactory(IWindsorContainer container)
{
this.container = container;
}
public override void ReleaseController(IController controller)
{
container.Kernel.ReleaseComponent(controller);
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
var controllerComponentName = controllerName + "Controller";
return container.Kernel.Resolve<IController>(controllerComponentName);
}
}
EDIT # 5 Se stai usando aree MVC, quanto sopra implementazione non funziona per voi.Sarà necessario registrare ogni controller in base al suo nome completo, e sovrascrivere GetControllerInstance invece di CreateController:
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
if (controllerType != null)
{
return (IController)container.Kernel.Resolve(controllerType);
}
return null;
}
MVC 3 è di 15 ore di vita già, qualcuno scrivere questo codice stat! – jfar
Sì ... la parte restituita null è la chiave, che non è così ovvia nel mio esempio se non si sa che Ninject ha quel metodo TryGet e restituisce null se non riesce a trovare una corrispondenza. Probabilmente avrei potuto essere più chiaro. :) –
Ogni possibilità che possiamo vedere più di questo codice. WindsorControllerActivator? dov'è, google risultati zero. – MvcCmsJon