2014-09-05 2 views
6

Я видел другие вопросы, подобные этому, но это не решило мою проблему. Пример одного вопроса: Unity register generic type for non generic interfaceUnity не может решить общий репозиторий

У меня есть Интерфейс

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

и класс

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

зарегистрировать его

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

и попытаться решить его

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

Он всегда возвращает null.

Я видел много разных источников, и все они показывают тот же способ его реализации. Почему это не работает?

UPDATE

Это фактическая реализация:

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

ответ

3

Вы должны удалить проверку if (Container.IsRegistered<T>()) в вашем коде, причиной этого будет возвращать false для каждого репозитория вы запрашиваете. Контейнерные репозитории, такие как IRepository<string>, IRepository<User> и т. Д., Не регистрируются в контейнере только в общей версии IRepository<T>.

Если вы хотите вернуть null, используйте блок try-catch около Container.Resolve, чтобы установить разрешенное значение null в случае исключения.

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

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

С вашим обновлением я понимаю. Таким образом, он фактически регистрирует общую «версию». Я изменил код и добавил блок try-catch, и теперь он работает. Я прошу вас удалить «= default (T)» в начале, потому что мы должны назначить default (T) для разрешения в catch. Тогда я отвечу в качестве решения. Спасибо. – Th3B0Y

2

Я сделал этот небольшой тест с Unity, чтобы попытаться понять вашу проблему (я должен был изменить метод GetById немного). Тем не менее, он работает так же, как и ожидалось, печатает 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

Когда я использую код exatly, как ваша, она работает хорошо. Я добавил свою реализацию (это просто). Взгляни, пожалуйста. – Th3B0Y

0

мне понравилась Jehof & ThB0Y ответ. Но мне не нравилось ловить исключение. Я написал собственный метод IsRegisteredInternal, чтобы проверить также нерешенные 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; 
    } 

Примечание: IsRegistered() перебирает через Container.Registrations

Смежные вопросы