我正在使用Unity来实例化我的MenuRepository实例。尝试这样做时,我收到以下错误。
类型列表`1有多个长度为1的构造函数。无法消除歧义。
我已尝试过以下注册,但没有运气..
container.RegisterType<IMenuRepository, MenuRepository>(
new PerThreadLifetimeManager(),
new InjectionConstructor(typeof(IMonopolyEntitiesDbContext),
typeof(List<MenuLink>)));
这是我的注册
container.RegisterType<MenuLink>();
container.RegisterType <List<MenuLink>>();
container.RegisterType<IMonopolyEntitiesDbContext, MonopolyEntities>(
new PerThreadLifetimeManager());
container.RegisterType<IMenuRepository, MenuRepository>(
new PerThreadLifetimeManager(),
new InjectionConstructor(typeof(IMonopolyEntitiesDbContext), typeof(List<MenuLink>)));
MenuRepository
public class MenuRepository : IMenuRepository
{
IMonopolyEntitiesDbContext _dbContext;
List<MenuLink> _allsubMenus;
public MenuRepository(IMonopolyEntitiesDbContext context, List<MenuLink> allsubMenus)
{
_dbContext = context;
_allsubMenus = allsubMenus;
}
}
答案 0 :(得分:3)
我使用了没有参数的InjectionConstructor。
using (var c = new UnityContainer())
{
c.RegisterType(typeof(List<string>), new InjectionConstructor());
c.RegisterType<IMyParamClass, MyParamClass>();
c.RegisterType<IMyClass, MyClass>(
new PerThreadLifetimeManager(),
new InjectionConstructor(typeof(IMyParamClass),
typeof(List<string>)));
var obj = c.Resolve<IMyClass>();
obj.write();
}
答案 1 :(得分:3)
您需要了解IoC容器的目标是将抽象映射到实现并从中构建对象图。因此,为了能够创建对象,Unity需要知道如何创建对象。但是,List<T>
不是您的典型服务类型。它有多个构造函数,因此Unity没有关于如何创建此类型的线索。
但即使它确实知道如何创建它(例如通过使用List<T>
的默认构造函数),这对你来说仍然没用,因为在这种情况下会向消费者注入一个空列表。这完全没有用。
所以你应该做的最少的事情就是确定要注入的内容。例如,通过这样做:
container.RegisterInstance<List<MenuLink>>(new List<MenuLink>
{
new MenuLink { Id = 1, Name = "foo" },
new MenuLink { Id = 2, Name = "bar" },
new MenuLink { Id = 3, Name = "foobar" },
});
这对您有用,因为您声明List<MenuLink>
实际上是一个单身,并且没有从数据库中填充。但是,在容器中注册此List<MenuLink>
仍然会有问题,因为现在可以将List<T>
注入任何消费者,而您永远不应该这样做。此List<MenuLink>
是MenuRepository
的实现细节,可能负责更新它。将List<MenuLink>
注入其他使用者是有风险的,因为List<T>
不是线程安全的。最好将此List<T>
保留在MenuRepository
内部,以便正确锁定。
因此,不是在容器中注册List<MenuLink>
,而是使用列表明确注册存储库,如下所示:
var menuLinks = new List<MenuLink>
{
new MenuLink { Id = 1, Name = "foo" },
new MenuLink { Id = 2, Name = "bar" },
new MenuLink { Id = 3, Name = "foobar" },
};
container.RegisterType<IMenuRepository, MenuRepository>(
new PerThreadLifetimeManager(),
new ParameterOverride("allsubMenus", menuLinks));