【发布时间】:2011-04-27 14:47:14
【问题描述】:
有谁知道是否可以使用 Ninject 来解决实例化过程之外的任何未解决的抽象依赖关系?我一直在研究构造函数注入与属性/方法/字段注入,但在我看来,Ninject 似乎仍然希望成为使用 IKernel.Get() 方法的类型的创建者。
基本上,我们使用 MVC3 来构建我们的产品,我们遇到了这样一种情况,我们希望默认的 ModelBinder 将表单值映射到对象的实例,然后能够在提交的 ViewModel 依赖于抽象接口,例如
public class InviteFriend {
[Required]
public string EmailAddress { get; set; }
public void Execute() {
var user = IUserRepository.GetUser(this.EmailAddress);
if (user == null) {
IUserRepository.SaveInvite(this.EmailAddress);
}
MailMessage toSend = new MailMessage(); // Obviously some logic to prepare the body, subject and other mail properties
SmtpClient.Send(toSend);
}
}
控制器操作将接收 InviteFriend 作为方法参数。我们希望 Ninject 能够解决 IUserRepository 依赖项,但我不知道如何解决,因为对象本身是由 MVC ModelBinder 而不是 Ninject IKernel.Get() 实例化的。
也许解决方案是基于 Ninject 的 ModelBinder,或者这似乎是一个非常糟糕的主意?
编辑添加:在下面的 cmets 之后,我意识到我匆忙模拟的代码示例并不能真正反映我们所面临的情况。我更新了代码示例以反映 InviteFriend.Execute() 的逻辑比仅在一个存储库上调用方法更复杂。潜在地,这是表示离散任务的逻辑,该任务可以协调多个不同领域对象和多个存储库之间的交互。存储库是抽象定义的,理想情况下将由 Ninject 解决。
【问题讨论】:
-
我觉得在模型中使用这样的方法是个坏主意——任何数据操作都应该由控制器完成。模型应该只代表数据和数据。
-
我同意 Lukas 的观点,即控制器应该有 IUserRepository 并且 InviteFriend 类应该只做它应该做的事情:代表用户输入数据。
-
这不会导致胖控制器吗?我的想法是,在 ViewModel 中使用这个逻辑,或者更好地称为命令样式对象,将业务逻辑保留在域对象中,然后更容易重用,而不是有效地将业务逻辑放在控制器操作方法中为复制粘贴样式的代码重用留出了余地。这样,Silverlight/WP7 应用程序可以重复使用相同的命令样式对象,而无需为相同的逻辑复制代码...
-
为什么不添加适当的业务层并将其注入控制器?
标签: asp.net-mvc-3 ninject