2012-07-21 13 views
13

Estoy intentando insertar una dependencia en la página de vista de diseño compartido para evitar tener que hacerlo en cada vista que usa el diseño.¿Puede Autofac inyectar dependencias en archivos de vista de diseño?

He seguido el guidance en la wiki para inyectar dependencias en vistas, pero la propiedad siempre es nula.

¿Puede Autofac inyectar propiedades en una página de vista personalizada que es un archivo de diseño?

Aquí está mi configuración. CustomViewPage

namespace MyApp 
{ 
    using System.Web.Mvc; 

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

~/views/Común/_Layout.cshtml

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

Registro Global ...

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)); 

Los puntos de vista "niños" que utilizan el diseño no se derivan de la página CustomViewPage.

+3

Parece que este es un [problema conocido] (http://code.google.com/p/autofac/issues/detail?id=349) de Autofac ... – nemesv

+0

Sí, el problema está aquí, http: // code .google.com/p/autofac/issues/detail? id = 349 – GraemeMiller

+1

Esta respuesta funcionó para mí como una solución: http://stackoverflow.com/a/14935006/789683 – flipchart

Respuesta

1

No es solo con AutoFac, básicamente, no se puede lograr DI en los diseños. Es posible que necesite una referencia al contenedor IOC en CustomViewPage para resolver las dependencias.

A menos que sea REALYYY REQUIRED solo evite DI en las vistas (solo mi opinión).

Desde mi punto de vista no veo muchos beneficios. Creo que no vas a escribir pruebas unitarias para la clase de página de vista básica, ¿verdad? a menos que haya alguna razón especial solo evítelo. En lugar de tener dependencia con el contenedor, es mejor tener dependencias con implementaciones concretas.

+3

Cualquier tipo de referencia o antecedentes sobre por qué puede DIs en diseños? – Josh

+0

@Josh como se dijo anteriormente, es mi opinión y muchas otras, nunca dije que no se puede simplemente que no sea la mejor idea ... Algunas razones por las que no, será difícil probar la unidad, dependiendo de Con la biblioteca IoC que vaya, necesitará acceder al HttpContext para resolver el contenedor y es probable que termine en una situación en la que su vista esté hablando directamente con un servicio, lo que frena el patrón MVC. Depende de todo el mundo cómo hacen las cosas y no estoy diciendo que no se puede simplemente que desee volver a pensar en el diseño y asegurarse de que no hay mejor opción –

+0

@Joe_DM ¿Puede publicar su edición como una nueva respuesta? ? – VJAI

0

Aquí hay un pequeño trabajo que funcionará con la mayoría de los marcos DI.

primero ajuste que CustomPageView un poco:

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

} 

Ahora bien necesita para obtener la dependencia en sus ViewData, introducir un atributo para hacer esto:

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); 
    } 
} 

en que método de acción o controlador :

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

Y en su opinión, ahora debería poder usar su Helper como expec Ted:

@Helper.HelloWorld() 

Ver this blog para el post original.

15

La mayoría de las soluciones será sólo una envoltura alrededor de la llamada DependencyResolver.Current.GetService, por lo que podría ser más fácil llamar directamente de diseño:

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

También de esta manera ayuda a que la página modelo más SRP, porque puede evitar mezclar rutinas/modelos de servicio y negocios.

0

Para obtener resultados sin parámetros, no necesita extender su WebViewPage para pasar datos a. Lo resolvería de esta manera: 1. Declare una clase HelperActionFilter derivada de ActionFilter, inyecte su servicio a través de la propiedad http://docs.autofac.org/en/latest/integration/mvc.html 2. Dentro de HelperActionFilter.OnActionExecuting setup ViewBag.HasFoo compruebe en el diseño.

0

Basta con crear página parcial e insertarla en la disposición de página:

@Html.Partial("_MyPartialPage"); 

Las dependencias se inyectan en las páginas parciales.

Cuestiones relacionadas