2010-09-15 18 views
9

我想注入依赖于我的MVC控制器这样统一框架IoC和默认构造函数

private static void RegisterContainer(IUnityContainer container) 
{    
    container 
     .RegisterType<IUserService, UserService>() 
     .RegisterType<IFacebookService, FacebookService>(); 
} 

的UserService类有这样的构造......

public UserService(): this(new UserRepository(), new FacebookService()) 
{ 
    //this a parameterless constructor... why doesnt it get picked up by unity? 
} 

public UserService(IUserRepository repository, IFacebookService facebook_service) 
{ 
    Repository=repository; 
    this.FacebookService=facebook_service; 
} 

异常我得到的是以下...

当前类型, Repositories.IUserRepository, 是一个接口,不能被 构建。您是否缺少映射类型 ?

它看起来像试图注入一个构造函数到服务,但默认就足够了?为什么它没有映射到无参数的构造函数?

+0

什么是'Repository'和'this.FacebookService'? – SwDevMan81 2010-09-15 03:22:56

回答

25

Unity默认约定(在文档中明确指出)是选择参数最多的构造函数。你不能只是简单地声明“IoC不会找到最具体的构造函数,如果你在注册类型时没有指定构造函数参数,它会自动调用默认构造函数。”每个容器实现可以并且确实具有不同的默认值。

在Unity的情况下,就像我说的那样,它会选择参数最多的构造函数。如果有两个参数最多的话,那么它会变得模棱两可并且抛出。如果你想要不同的东西,你必须配置容器来做到这一点。

你的选择是:

放在你想叫构造函数[InjectionConstructor]属性(不推荐,但快速和容易)。

使用API​​:

container.RegisterType<UserService>(new InjectionConstructor()); 

使用XML配置:

<container> 
    <register type="UserService"> 
    <constructor /> 
    </register> 
</container> 
+0

温莎城堡选择了最匹配的构造函数,而Unity仍然不能。 – 2015-08-08 21:18:12

+0

这是一个故意的折衷。 Unity可以解决没有在容器中注册的具体类型,Windsor无法知道。这使得“最佳匹配”确实含糊不清,所以我们采用了更确定的默认值。 – 2015-08-08 23:04:11

+1

感谢您的澄清。我看到我的评论包含不必要的强烈论据。这应该是“单位不自动选择构造函数”而不是“不能”:)看起来他们选择了其他路径设计决策以及http://stackoverflow.com/a/499675/929902无论如何,我很高兴与统一和与它的灵活性。 – 2015-08-09 02:03:10

0

我无法专门针对Unity,但IoC容器通常会尝试使用他们可以找到的最具体的构造函数,因为它是构造函数

如果有一个构造函数需要两个注入依赖关系,那么推测它们是使用该对象所必需的;如果容器调用它,默认的构造函数将不得不做一些事情来完成它们。容器的工作是完成依赖关系,那么如果没有指示让它继续上课,为什么还要让班级这样做呢?

为了您的具体问题,根据您的代码:

private static void RegisterContainer(IUnityContainer container) 
{    
    container 
     .RegisterType<IUserService, UserService>() 
     .RegisterType<IFacebookService, FacebookService>(); 
} 

IUserRepository未注册。添加一条线如

.RegisterType<IUserRepository, UserRepository>() 
+0

IoC会找到最具体的构造函数,如果在注册类型时没有指定构造函数参数,它会自动调用默认构造函数。 – TalentTuner 2010-09-15 03:38:18

+0

我不知道你使用过哪些容器,但我几乎从不在映射中指定构造函数。我确实知道StructureMap会更喜欢一个更完美的构造函数给默认构造函数 - 我在当前项目中使用它,这就是我如何测试一些必须具有默认构造函数的对象(例如WCF Services,例如)。我很确定温莎城堡也会更喜欢更具体的构造函数。 – arootbeer 2010-09-15 03:42:44

+1

@saurabh在我的Unity经验中,当没有指定参数时,使用最具体的构造函数。 – 2010-09-15 03:54:38