我看到了类似的其他问题,但它并没有解决我的问题。一个问题的示例:Unity register generic type for non generic interface
我有界面
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。
我看到了许多不同的来源,他们都表现出相同的实现方式。为什么不起作用?
更新
这是实际的实施:
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);
}
}
答案 0 :(得分:3)
您应该删除代码中的检查if (Container.IsRegistered<T>())
,因为这会为您请求的每个存储库返回false
。像IRepository<string>
,IRepository<User>
等混凝土存储库未在容器中仅注册IRepository<T>
的通用版本。
如果要返回null
,请在Container.Resolve
周围使用try-catch-block,以便在出现异常时将其解析为null。
public static T Resolve<T>()
{
T resolved;
//if (Container.IsRegistered<T>())
try{
resolved = Container.Resolve<T>();
}
catch(Exception){
resolved = default(T);
}
return resolved;
}
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
我喜欢 Jehof&amp; ThB0Y 回答。但我不喜欢捕捉异常。我编写了自己的IsRegisteredInternal方法来检查未解析的泛型。
from lxml import html
h = html.fromstring('''<div id="outer">
<div id="inner" class="content body">
text
</div></div>''')
content = h.cssselect('div.content')[0]
content.text
# output :
# '\n text\n'
from cssselect import GenericTranslator
GenericTranslator().css_to_xpath('div.content')
# output :
# u"descendant-or-self::div[@class and contains(concat(' ', normalize-space(@class), ' '), ' content ')]"
注意:IsRegistered()通过Container.Registrations枚举