2009-06-17 26 views
9

Mi pregunta es la siguiente: Tengo un controlador base (controlador ASP.Net MVC) llamado ApplicationController, y quiero que todo mi controlador herede de él. este controlador base tiene una propiedad ILogger, marcada con un atributo [Dependencia]. (sí, sé que debería usar inyección de constructor, solo tengo curiosidad sobre este atributo).Unity [dependencia] inyección y Herencia

Creé el contenedor, registré los tipos, cambié la fábrica por defecto, todo está bien. el problema es que cuando trato de usar mi propiedad Logger en el controlador derivado, no se resuelve.

¿Qué estoy haciendo mal? ¿Por qué el contenedor no resuelve las dependencias de la clase base al crear el controlador derivado?

ejemplos de código:


ApplicationController:

public class ApplicationController : Controller 
{ 
    [Dependency] 
    protected ILogger _logger { get; set; } 

} 

controlador derivado:

public class HomeController : ApplicationController 
{ 
    public HomeController() 
    { 

    } 
    public ActionResult Index() 
    { 
     _logger.Log("Home controller constructor started."); 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 

    public ActionResult About() 
    { 
     return View(); 
    } 
} 

Unidad fábrica controlador:

public class UnityControllerFactory : DefaultControllerFactory 
{ 
    private readonly IUnityContainer _container; 
    public UnityControllerFactory(IUnityContainer container) 
    { 
     _container = container; 
    } 

    protected override IController GetControllerInstance(Type controllerType) 
    { 
     return _container.Resolve(controllerType) as IController; 
    } 
} 

Global.asax.cs muestra:


Soy bastante nuevo a la unidad, así que tal vez hice algo mal.

gracias, Ami.

+0

¿Funciona esto para el controlador de aplicaciones? –

+0

¿Conseguiste que esto funcionara alguna vez? Mi código es casi idéntico y tampoco puedo resolver el controlador base. ¿Nadie? –

+0

Ray: funcionó después de hacer públicas las propiedades. ese es un precio que tiene que pagar para que funcione Unity. – Ami

Respuesta

18

AFAIK, Unity solo resolverá las propiedades públicas. Por lo tanto, su propiedad protegida no se resolverá.

+0

OK, Jakob obtiene 2 puntos :) cambiando la propiedad al público resolvió el problema. el contenedor de Unity resolvió la dependencia y todo está bien. – Ami

0

No estoy seguro de si esto está relacionado, pero por lo general, evito tener espacios de nombres y clases con el mismo nombre (en su caso, Logger.Logger), porque tuve problemas con esto en el pasado. Pero ese puede no ser el problema.

Tampoco estoy seguro de si el atributo [Dependency] funciona para los tipos derivados. Si lo cambia por inyección de constructor, ¿esto todavía no funciona? Algo así como:

public class ApplicationController : Controller 
{ 
    protected ILogger _logger { get; set; } 


    public ApplicationController(ILogger logger) 
    { 
     this._logger = logger; 

    } 
} 

y

public class HomeController : ApplicationController 
{ 
    public HomeController(ILogger logger) : base(logger) 
    { 

    } 
    public ActionResult Index() 
    { 
     _logger.Log("Home controller constructor started."); 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 

    public ActionResult About() 
    { 
     return View(); 
    } 
} 

y el resto de la misma. El código se ve bien

0

Soy bastante inexperto con la unidad también, pero creo que debe registrar su HomeController con el contsaner, no el registrador.

+1

Es correcto registrar el registrador porque desea inyectar su dependencia (una implementación de ILogger). –

0

Tuve el mismo problema y lo solucioné cambiando el ILogger al público. Esto es con un proyecto ASP.NET MVC2 en VS2010, .NET 4. Tiene sentido, lógicamente, ya que Unity no está creando una clase de proxy ni nada, solo está configurando propiedades a las que tiene acceso, y tiene una asignación para - por lo tanto, solo público.

Cuestiones relacionadas