2012-02-03 6 views
22

Mam kod, który wygląda mniej więcej tak. Kiedy próbowałem zrobić ResolveAll oczekiwałem, że każdy typ zarejestrowany przy użyciu IParserType będzie pochodził z instancji kontenera. Ale nie dostałem żadnej instancji od Unity. Czy zakładam tutaj coś złego?ResolveAll nie działa

public class ResolveAllDemo 
{ 
    public ResolveAllDemo() 
    { 
     var container = new UnityContainer(); 

     container.RegisterInstance<IUnityContainer>(container); 
     container.RegisterType<IParser, SuperParser>(); 
     container.RegisterType<IParser, DefaultParser>(); 
     container.RegisterType<IParser, BasicParser>(); 
     // container.RegisterType<Crawler>(); 
     container.RegisterType<IParserFactory, UnityParserFactory>(); 

     foreach (var registeredMember in container.ResolveAll<IParser>()) 
     { 
      LoggingUtility.LogerInstance.Logger.Write(registeredMember); 
     } 
    } 

    #region Resolve Demo 

    public interface IParserFactory 
    { 
     IEnumerable<IParser> BuildParsers(); 
    } 

    public class UnityParserFactory : IParserFactory 
    { 
     private IUnityContainer _container; 

     public UnityParserFactory(IUnityContainer container) 
     { 
      _container = container; 
     } 

     public IEnumerable<IParser> BuildParsers() 
     { 
      return _container.ResolveAll<IParser>(); 
     } 
    } 

    public class DefaultParser : IParser 
    { 
     public override string ToString() 
     { 
      return "DefaultParser"; 
     } 
    } 

    public class BasicParser : IParser 
    { 
     public override string ToString() 
     { 
      return "BasicParser"; 
     } 
    } 

    public class SuperParser : IParser 
    { 
     public override string ToString() 
     { 
      return "SuperParser"; 
     } 
    } 

    public interface IParser 
    { 
    } 

    #endregion Resolve Demo 
} 

Odpowiedz

46

Nie rejestrujesz 3 różnych implementacji IParser. Tworzysz domyślne mapowanie IParser -> , a następnie zastępujesz je IParser ->DefaultParser, a następnie zastępujesz je ponownie IParser ->BasicParser.

Jeśli chcesz zarejestrować wszystkie trzy z nich trzeba zapewnić nazwanych rejestracje jak

container.RegisterType<IParser, SuperParser>("Super"); 
container.RegisterType<IParser, DefaultParser>("Default"); 
container.RegisterType<IParser, BasicParser>("Basic"); 

Ponadto ResolveAll nie obejmuje domyślne odwzorowanie (ten bez nazwy). Usuwa tylko te mapowania z IParser, które zostały zarejestrowane jako nazwane odwzorowania.

+1

Czy wiesz, czy fakt, że wartość domyślna nie została zwrócona, jest zgodna z projektem, czy jest to błąd? –

+0

@NicolasIrisarri Oprócz tego, że jest w kodzie źródłowym od co najmniej wersji 1.2, myślę, że jest to zgodne z projektem. Możesz łatwo obejść go, jeśli ponownie zarejestrujesz domyślne mapowanie z nazwą (np. "Default"). –

+1

to naprawdę jest cenna informacja. Jedność zachowująca się w ten sposób nie ma żadnego sensu. – vip32

11

Musisz zarejestrować swoje parsery z nazwą, jeśli chcesz rozwiązać wszystkie parserów z kontenera.

Here's Kodeksu aktualizacja z konstruktora:

public ResolveAllDemo() 
{ 

    var container = new UnityContainer(); 

    container.RegisterType<IParser, SuperParser>("SuperParser"); 
    container.RegisterType<IParser, DefaultParser>("DefaultParser"); 
    container.RegisterType<IParser, BasicParser>("BasicParser"); 

    container.RegisterType<IParserFactory, UnityParserFactory>(); 

    foreach (var registeredMember in container.ResolveAll<IParser>()) 
    { 
    LoggingUtility.LogerInstance.Logger.Write(registeredMember); 
    } 
} 

Uwaga:

Nie ma potrzeby na poniższym kodzie powodują rejestry samego pojemnika w trakcie budowy zbiornika.

container.RegisterInstance<IUnityContainer>(container); 
// not needed cause UnityContainer registers itself on construction 
+0

Dziękuję, twoja odpowiedź naprawdę uratowała mnie dzisiaj dużo debugowania! –