Я видел другие вопросы, похожие на этот, но это не решило мою проблему. Пример одного вопроса: Общий тип регистра Unity для неуниверсального интерфейса

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

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

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

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

ОБНОВЛЕНИЕ

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

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);
    }
}
6
Th3B0Y 5 Сен 2014 в 16:13

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;
}
3
Th3B0Y 5 Сен 2014 в 17:17
С вашим обновлением я понимаю. Таким образом, он фактически регистрирует общую «версию». Я изменил код и добавил блок try-catch, и теперь он работает. Прошу убрать "= default(T)" в начале, т.к. мы должны присвоить default(T) разрешение в улове. Тогда я поставлю ваш ответ как решение. Спасибо.
 – 
Th3B0Y
5 Сен 2014 в 16:56

Я провел этот небольшой тест с 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();
    }
}
2
AndreySarafanov 5 Сен 2014 в 16:26
Когда я использую код точно так же, как ваш, он тоже работает. Я добавил свою реализацию (это просто). Пожалуйста, взгляните.
 – 
Th3B0Y
5 Сен 2014 в 16:40

Мне понравился ответ Jehof & ThB0Y . Но мне не нравилось ловить исключение. Я написал свой собственный метод IsRegisteredInternal для проверки наличия неразрешенных универсальных шаблонов.

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

0
Bhargava Mummadireddy 18 Фев 2016 в 17:00