如何解决对象初始化之后,Ninject可以解析抽象依赖吗?
| 有谁知道有可能使用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,或者这真的不是一个好主意吗?
编辑:在下面的评论之后,我意识到我匆忙模拟的代码示例并没有真正反映我们所面临的问题。我已经更新了代码示例,以反映InviteFriend.Execute()的逻辑比仅在一个存储库上调用方法更为复杂。潜在地,这是代表离散任务的逻辑,该任务可以协调多个不同域对象和多个存储库之间的交互。存储库是抽象定义的,理想情况下将由Ninject解决。
解决方法
我认为您正在寻找的是以下情况:
public class InviteFriend {
[Required]
public string EmailAddress { get; set; }
// More information
}
public interface ICommand {
void Execute();
}
public class InviteFriendCommand : ICommand
{
public InviteFriend(InviteFriend info,IUserRepository userRepo,IMailSender mailSender) {
this.inviteFriend = info;
this.userRepo = userRepo;
this.mailSender = mailSender;
}
public void Execute() {
var user = this.userRepo.GetUser(this.inviteFriend.EmailAddress);
if (user == null) {
this.userRepo.SaveInvite(this.inviteFriend.EmailAddress);
}
MailMessage toSend = new MailMessage(); // Obviously some logic to prepare the body,subject and other mail properties
this.mailSender.Send(toSend);
}
}
public interface ICommandFactory {
ICommand CreateInviteFriendCommand(InviteFriend info);
}
public class CommandFactory {
public CommandFactory(IResolutionRoot resolutionRoot) {
this.resolutionRoot = resolutionRoot;
}
ICommand CreateInviteFriendCommand(InviteFriend info) {
this.resolutionRoot.Get<InviteFriendCommand>(new ConstructorArgument(\"info\",info));
}
}
public class YourController {
// Somewhere
var command = this.commandFactory.CreateInviteFriendCommand(info);
command.Execute();
}
public class YourModule : NinjectModule {
override Load() {
Bind<IUserRepository>().To<UserRepo>().InRequestScope();
Bind<ICommandFactory>().To<CommandFactory>().InRequestScope();
Bind<InviteFriendCommand>().ToSelf().InRequestScope();
}
}
请稍等一下,请原谅我。我和我的大脑外编译器一起破解了它;)
,感谢您的所有评论,但后来我找到了所需要的信息。
答案是可以在实例化后使用Ninject注入依赖项。解决方法如下:
public class InviteFriend {
[Inject]
public IUserRepository UserRepo { get; set; }
[Required]
public string EmailAddress { get; set; }
public void Execute() {
var user = UserRepo.GetUser(this.EmailAddress);
if (user == null) {
UserRepo.SaveInvite(this.EmailAddress);
}
MailMessage toSend = new MailMessage(); // Obviously some logic to prepare the body,subject and other mail properties
SmtpClient.Send(toSend);
}
}
使用客户端代码,然后使用Ninject内核,如下所示:
IKernel container = new StandardKernel(new ModuleWithMyBindings());
container.Inject(instanceOfInviteFriend);
该代码本身比之复杂得多,即我不需要每次都实例化一个新的IKernel。
我意识到这在结构上不如评论中提出的一些建议纯净,但是按照YAGNI的精神,这已经足够了,我们以后可以随时使用Daniel的答案中的一些好的建议进行重构。 。但是,这是有关Ninject功能的问题,而不是体系结构审查问题,这就是我认为自己的问题的答案:)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。