2011-10-12 5 views
6

La mia pagina di base assomiglia:Tipo di pagina di base personalizzato per le mie visualizzazioni del rasoio, come utilizzare il windsor del castello per le proprietà autowire?

namespace ASDF.Mvc.ViewEngines.Razor 
{ 
    public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel> 
    { 

     public ISomeHelper SomeHelper { get; set; } 
    } 
} 

Le mie opinioni/web.config

<system.web.webPages.razor> 
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
    <pages pageBaseType="ASDF.Mvc.ViewEngines.Razor.WebViewPage"> 
     <namespaces> 
     <add namespace="System.Web.Mvc" /> 
     <add namespace="System.Web.Mvc.Ajax" /> 
     <add namespace="System.Web.Mvc.Html" /> 
     <add namespace="System.Web.Routing" /> 
     </namespaces> 
    </pages> 
    </system.web.webPages.razor> 

Come posso avere questo cablata in modo tale che SomeHelper sarà cablato con Castle.

Questo sta tornando nullo al momento, Ho già cablato ISomeHelper e le cose funzionano correttamente per i miei controller/repository/classi di servizio.

Immagino che questa WebViewPage sia chiamata da qualche parte dove il mio contenitore non ha accesso (come a livello di controller).

Come posso farlo funzionare?

risposta

9

La prima cosa relativa all'iniezione di dipendenza in pagine Web personalizzate come questa è che non è possibile utilizzare l'iniezione del costruttore. È un peccato e spero che miglioreranno questo nelle versioni future. Il motivo è che la classe effettiva che implementa questo viene emessa dinamicamente in fase di runtime dal motore ASP.NET.

Quindi non possiamo usare l'iniezione di proprietà al momento.

Quindi una possibilità è utilizzare un numero personalizzato IDependencyResolver. Sfortunatamente IDependencyResolver doesn't play nice with Castle Windsor. Ad esempio, sarebbe stato un pezzo di torta con Ninject. Tutto quello che dovete fare è di decorare la proprietà con l'attributo SomeHelper[Inject]:

[Inject] 
public ISomeHelper SomeHelper { get; set; } 

e sarebbe stato cablato automaticamente Ninject in quanto utilizza un'IDependencyResolver personalizzato. Temo che con Windsor dovrai farlo manualmente. Così si potrebbe rendere il vostro contenitore pubblica in Global.asax e quindi:

public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel> 
{ 
    protected WebViewPage() 
    { 
     SomeHelper = MvcApplication.WindsorContainer.Resolve<ISomeHelper>(); 
    } 

    public ISomeHelper SomeHelper { get; set; } 
} 

so che questo fa schifo ma temo è la dura realtà. O forse passare a Ninject? Funziona davvero bene con ASP.NET MVC 3 e il suo IDependencyResolver.

+0

Come funziona l'iniezione di proprietà nei miei controller? – Blankman

+0

attendere, quindi devo impostare manualmente eventuali dipendenze di SomeHelper a destra? – Blankman

+1

@Blankman, l'iniezione delle dipendenze funziona nei controller perché è stata utilizzata una factory provider di controller personalizzata che utilizza windsor per iniettare tali dipendenze. Per quanto riguarda la tua seconda domanda sulle dipendenze di SomeHelper, non è necessario impostarle manualmente. Si impostano queste dipendenze nello stesso modo in cui si farebbe se si trattasse di una dipendenza del controllore. Quando usi '.Risolvi () 'questo fornirà automaticamente dipendenze registrate. –

0

Penso che quello che vorrai fare sia collegarti alla posizione di servizio di MVC3 per controllare come vengono create le pagine di visualizzazione. Non ho ancora usato MVC3, ma ho trovato an article that describes the Service Location feature e questo potrebbe darti il ​​"gancio" necessario per poter accedere a WebViewPage prima che venga elaborato.

Accedendo a WebViewPage prima che venga elaborato, è possibile utilizzare Windsor per eseguire l'iniezione di proprietà della pagina di visualizzazione. Per impostazione predefinita, Windsor esegue solo l'iniezione del costruttore, ma è possibile trovare uno sample of doing property injection via an extension method in un post sul blog che ho fatto un paio di anni fa su MVC1 ActionFilters.

+0

il mio sta facendo l'iniezione di proprietà bene, non sono sicuro di quello che ho fatto, ma è workign con quello. – Blankman