2014-09-05 16 views
6

Ho visto altre domande simili a questa, ma non ha risolto il mio problema. Esempio di una domanda: Unity register generic type for non generic interfaceUnity non può risolvere il repository generico

ho l'interfaccia

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

e la classe

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

mi registro che

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

e cercare di risolverlo

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

Restituisce sempre null.

Ho visto molte fonti diverse e tutte mostrano lo stesso modo di implementarlo. Perché non funziona?

UPDATE

Questa è l'implementazione effettiva:

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

risposta

3

È necessario rimuovere il controllo if (Container.IsRegistered<T>()) nel codice, causare questo tornerà false per ogni repository si richiede. I repository di concreti come IRepository<string>, IRepository<User> ecc. Non sono registrati nel contenitore solo la versione generica di IRepository<T>.

Se si desidera restituire null, quindi utilizzare un blocco try-catch-block intorno a Container.Resolve per impostare risolto su null in caso di un'eccezione.

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

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

Con il tuo aggiornamento capisco. Quindi registra effettivamente la "versione" generica. Ho cambiato il codice e aggiunto il blocco try-catch e ora funziona. Vi chiedo di rimuovere "= default (T)" all'inizio, perché dovremmo assegnare il valore predefinito (T) a quello risolto. Quindi stabilirò la tua risposta come soluzione. Grazie. – Th3B0Y

2

Ho fatto questo piccolo test con Unity per cercare di capire il vostro problema (ho dovuto cambiare il metodo di GetById un po '). Tuttavia, funziona proprio come previsto, stampe 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

Quando uso il codice exatly come la tua, funziona pure. Ho aggiunto la mia implementazione (è semplice). Per favore dai un'occhiata. – Th3B0Y

0

mi è piaciuto Jehof & ThB0Y risposta. Ma non mi piaceva prendere un'eccezione. Ho scritto il mio metodo IsRegisteredInternal per controllare anche generici non risolti.

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

Nota: IsRegistered() enumera attraverso Container.Registrations

Problemi correlati