Я видел другие вопросы, похожие на этот, но это не решило мою проблему. Пример одного вопроса: Общий тип регистра 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);
}
}
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;
}
Я провел этот небольшой тест с 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();
}
}
Мне понравился ответ 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
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.