2014-09-05 15 views
6

Widziałem inne pytania podobne do tego, ale to nie rozwiązało mojego problemu. Przykładem jednego pytania: Unity register generic type for non generic interfaceJedność nie może rozwiązać Generic Repository

I przyjmujemy, że interfejs

public interface IRepository<T> 
    { 
     T GetById(int id); 
    } 

a klasa

public class Repository<T> : IRepository<T> 
    { 
     public T GetById(int id) 
     { 
      Console.WriteLine("Type: " + GetType()); 
      return default(T); 
     } 
    } 

ją zarejestrować

Container.RegisterType(typeof(IRepository<>), typeof(Repository<>)); 

i spróbować go rozwiązać

IRepository<string> IRepository = Container.Resolve<IRepository<string>>(); 

Zawsze zwraca wartość null.

Widziałem wiele różnych źródeł i wszystkie pokazują ten sam sposób realizacji. Dlaczego to nie działa?

UPDATE

Jest to rzeczywista realizacja:

public class Program 
{ 
    static Program() 
    { 
     DIDefaultRegisters.Initialize(); 
    } 

    public static void Main(string[] args) 
    { 
     var iRepository = UnityDIFacade.Resolve<IRepository<string>>(); 

     iRepository.GetById(1); 
    } 
} 

public class DIDefaultRegisters 
{ 
    public static void Initialize() 
    { 
     Register(typeof(IRepository<>),typeof(Repository<>)); 
    } 

    private static void Register(Type from, Type to) 
    { 
     UnityDIFacade.RegisterType(from, to); 
    } 
} 

public class UnityDIFacade 
{ 
    private static readonly IUnityContainer Container; 

    static UnityDIFacade() 
    { 
     IUnityContainer container = new UnityContainer(); 

     var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
     if (section != null) 
      section.Configure(container); 

     Container = container; 
    } 

    public static T Resolve<T>() 
    { 
     T resolved = default(T); 

     if (Container.IsRegistered<T>()) 
      resolved = Container.Resolve<T>(); 

     return resolved; 
    } 

    public static void RegisterType(Type from, Type to) 
    { 
     Container.RegisterType(from, to); 
    } 
} 

Odpowiedz

3

Należy usunąć zaznaczenie if (Container.IsRegistered<T>()) w kodzie, bo to powróci false dla każdego repozytorium życzenie. Repozytoriów konkrety, takich jak IRepository<string>, IRepository<User> itp. Nie są zarejestrowane w pojemniku tylko ogólna wersja IRepository<T>.

Jeśli chcesz zwrócić null, użyj bloku próbnego-catch o numerze Container.Resolve, aby ustawić wartość rozstrzygniętą na wartość null w przypadku wyjątku.

public static T Resolve<T>() 
{ 
    T resolved; 

    //if (Container.IsRegistered<T>()) 
    try{ 
     resolved = Container.Resolve<T>(); 
    } 
    catch(Exception){ 
     resolved = default(T); 
    } 
    return resolved; 
} 
+0

Z twoją aktualizacją Rozumiem. Więc faktycznie rejestruje ogólną "wersję". Zmieniłem kod i dodałem blok try-catch, który teraz działa. Proszę, usuń "= domyślnie (T)" na początku, ponieważ powinniśmy przypisać wartość domyślną (T) do rozstrzygnięcia w haczyku. Wtedy ustawię twoją odpowiedź jako rozwiązanie. Dziękuję Ci. – Th3B0Y

2

Zrobiłem ten mały test z Unity, aby spróbować zrozumieć problem (miałem zmienić metodę GetById trochę). Jednak to działa tak jak oczekiwano, drukuje Type: System.DateTime

public interface IRepository<T> 
{ 
    T GetById(int id); 
} 
public class Repository<T> : IRepository<T> 
{ 
    public T GetById(int id) 
    { 
     Console.WriteLine("Type: " + typeof(T)); 
     return default(T); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var container = new UnityContainer(); 
     container.RegisterType(typeof(IRepository<>), typeof(Repository<>)); 

     IRepository<DateTime> iRepository = container.Resolve<IRepository<DateTime>>(); 

     iRepository.GetById(4); 
     Console.ReadLine(); 
    } 
} 
+0

Kiedy użyć kodu exatly jak twoje, to działa również. Dodałem moją implementację (to proste). Proszę spojrzeć. – Th3B0Y

0

lubiłem Jehof & ThB0Y odpowiedź. Ale nie lubiłem wychwytywać wyjątków. Napisałem własną metodę IsRegisteredInternal, aby sprawdzić również nierozwiązane generics.

public static T Resolve<T>() 
    { 
     T ret = default(T); 

     if (IsRegisteredInternal<T>()) 
     { 
      ret = Container.Resolve<T>(); 
     } 

     return ret; 
    } 

    private static bool IsRegisteredInternal<T>() 
    { 
     if (Container.IsRegistered<T>()) 
      return true; 
     if (typeof(T).IsGenericType) 
     { 
      return Container.IsRegistered(typeof(T).GetGenericTypeDefinition()); 
     } 
     return false; 
    } 

Uwaga: IsRegistered() wylicza poprzez Container.Registrations

Powiązane problemy