2012-07-21 3 views
13

Sto provando a iniettare una dipendenza nella pagina di visualizzazione del layout condiviso per evitare di doverlo fare in ogni vista che utilizza il layout.Can Autofac può iniettare dipendenze nei file di visualizzazione del layout?

Ho seguito lo guidance nella wiki per iniettare dipendenze in viste, ma la proprietà è sempre nullo.

Can Autofac può iniettare proprietà in una pagina di visualizzazione personalizzata che è un file di layout?

Ecco il mio setup. CustomViewPage

namespace MyApp 
{ 
    using System.Web.Mvc; 

    public abstract class CustomViewPage : WebViewPage 
    { 
     public IHelper Helper { get; set; } 
    } 
} 

~/Vista/shared/_Layout.cshtml

@inherits MyApp.CustomViewPage 
<!DOCTYPE html> 
<html> 
... 
@if(this.Helper.HasFoo()){@Html.ActionLink("Bar")} 

registrazione globale ...

builder.RegisterType<Helper>().AsImplementedInterfaces(); 
builder.RegisterModelBinderProvider(); 
builder.RegisterFilterProvider(); 
builder.RegisterModule(new AutofacWebTypesModule()); 
builder.RegisterSource(new ViewRegistrationSource()); 
var container = builder.Build(); 
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

I punti di vista "bambini" che utilizzano il layout non derivano da la CustomViewPage.

+3

Sembra che questo sia un [problema noto] (http://code.google.com/p/autofac/issues/detail?id=349) di Autofac ... – nemesv

+0

Sì, il problema è qui http: // code .google.com/p/autofac/issues/detail? id = 349 – GraemeMiller

+1

Questa risposta ha funzionato per me come soluzione temporanea: http://stackoverflow.com/a/14935006/789683 – flipchart

risposta

1

Non è solo con AutoFac che in pratica non è possibile ottenere DI in layout. Potrebbe essere necessario un riferimento al contenitore IOC in CustomViewPage per risolvere le dipendenze.

A meno che non sia REALYYYYYYYY basta evitare DI in visualizzazioni (solo la mia opinione).

Dal mio punto di vista non vedo molti benefici. Penso che non hai intenzione di scrivere test unitari per la classe di visualizzazione di base della classe, vero? a meno che non ci sia una ragione speciale, basta evitarlo. Invece di avere dipendenza dal contenitore è meglio avere dipendenze con implementazioni concrete.

+3

Qualsiasi tipo di riferimento o sfondo nel motivo per cui è possibile 't DI in layout? – Josh

+0

@Josh come detto sopra, è la mia opinione e molti altri, non ho mai detto che non è possibile che non sia probabilmente l'idea migliore ... Alcuni motivi per non farlo, sarà difficile testare l'unità, a seconda di Con quale libreria IoC andrai avrai bisogno di accedere a HttpContext per risolvere il contenitore e probabilmente finirai in una situazione in cui la tua vista sta parlando direttamente a un servizio, quindi frenando il pattern MVC. Sta a tutti come fanno le cose e non sto dicendo che non puoi solo pensare che potresti voler ripensare al design e assicurarti che non ci sia l'opzione migliore –

+0

@Joe_DM Puoi postare la tua modifica come una nuova risposta ? – VJAI

0

Ecco un piccolo lavoro che funziona con la maggior parte dei framework DI.

regolare prima si CustomPageView un po ':

public abstract class CustomViewPage : WebViewPage 
{ 
    public IHelper Helper { 
     get { return ViewData[Helper.ViewDataKey] as IHelper; }  
    } 

} 

Ora bene necessario per ottenere la dipendenza nei vostri Viewdata, introdurre un attributo per fare questo:

public sealed class HelperAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     var viewResult = filterContext.Result as ViewResult; 
     if (viewResult != null) 
      viewResult.ViewData.Add(Helper.ViewDataKey, GetHelperFromIoC()); 

     base.OnResultExecuting(filterContext); 
    } 
} 

Su di te metodo di azione o del controller :

[Helper] 
public ActionResult Index() 
{ 
    return View(); 
} 

E a suo avviso si dovrebbe ora essere in grado di utilizzare il vostro aiuto come Expec Ted:

@Helper.HelloWorld() 

Vedere this blog per il post originale.

15

La maggior parte delle soluzioni sarà solo un wrapper per DependencyResolver.Current.GetService chiamata, quindi potrebbe essere più facile chiamare direttamente dal layout:

@{ 
    var helper = DependencyResolver.Current.GetService<IHelper>(); 
} 
... 
@if (helper.HasFoo()) { @Html.ActionLink("Bar") } 
... 

Anche in questo modo contribuisce a rendere la pagina modello più SRP, perché può evitare di mescolare routine/modelli di servizio e attività commerciali.

0

Per il risultato senza parametri non è necessario estendere la pagina WebView per passare i dati. Vorrei risolverlo in questo modo: 1. Dichiarare una classe HelperActionFilter derivata da ActionFilter, iniettare il servizio su di esso tramite la proprietà http://docs.autofac.org/en/latest/integration/mvc.html 2. Dentro HelperActionFilter.OnActionExecuting setup ViewBag.HasFoo controllarlo nel layout.

0

Basta creare pagina parziale e inserirlo nel layout di pagina:

@Html.Partial("_MyPartialPage"); 

dipendenze vengono iniettate in pagine parziali.