2009-06-17 18 views
9

La mia domanda è la seguente: Ho un controller di base (controller ASP.Net MVC) chiamato ApplicationController, e voglio che tutto il mio controller erediti da esso. questo controller di base ha una proprietà ILogger, contrassegnata con un attributo [Dependency]. (sì, so che dovrei usare l'iniezione del costruttore, sono solo curioso di questo attributo).Unity [dipendenza] iniezione ed Eredità

Ho creato il contenitore, i tipi registrati, modificato la fabbrica predefinita, tutto è a posto. il problema è che quando provo ad usare la mia proprietà Logger nel controller derivato, non è risolto.

cosa sto facendo di sbagliato? perché il contenitore non risolve le dipendenze della classe base durante la creazione del controller derivato?

esempi di codice:


ApplicationController:

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

} 

regolatore derivato:

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

Unità di controllo di fabbrica:

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 campione:


Sono abbastanza nuovo per l'Unità, quindi forse ho fatto qualcosa di sbagliato.

grazie, Ami.

+0

Funziona per il controller dell'applicazione? –

+0

Hai mai funzionato? Il mio codice è quasi identico e non riesco a risolvere neanche il controller di base. Chiunque? –

+0

Ray: ha funzionato dopo aver reso pubbliche le proprietà. questo è un prezzo che devi pagare per far lavorare Unity. – Ami

risposta

18

AFAIK, Unity risolverà solo proprietà pubbliche. Pertanto la tua proprietà protetta non verrà risolta.

+0

OK, Jakob ottiene 2 punti :) cambiando la proprietà al pubblico risolto il problema. il contenitore Unity ha risolto la dipendenza e tutto va bene. – Ami

0

Non sono sicuro se questo è collegato, ma di solito, evito di avere spazi dei nomi e classi con lo stesso nome (nel tuo caso, Logger.Logger), perché ho avuto problemi con questo in passato. Ma questo potrebbe non essere il problema.

Non sono nemmeno sicuro se l'attributo [Dipendenza] funzioni per i tipi derivati. Se lo modifichi per l'iniezione del costruttore, non funziona ancora? Qualcosa di simile:

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


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

    } 
} 

e

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

e il resto lo stesso. Il codice sembra ok.

0

Sono abbastanza inesperto anche con l'unità, ma penso che sia necessario registrare il tuo HomeController con il contsaner, non con il logger.

+1

È corretto registrare il registratore perché si desidera iniettare la dipendenza (un'implementazione di ILogger). –

0

Ho avuto lo stesso problema e l'ho risolto cambiando l'ILogger in pubblico. Questo è con un progetto ASP.NET MVC2 in VS2010, .NET 4. Ha senso, logicamente, dal momento che Unity non sta creando una classe proxy o altro, è solo l'impostazione delle proprietà a cui ha accesso e ha una mappatura per - quindi solo pubblico.