我可以为这个特定的情况在Ninject中指定作用域吗?

5

之前我提出了这个问题。得到的答案又引发了另一个问题,就像在你面前看到的那样。

最初的问题

我的问题是,我有一个使用ObjectContext的自定义MembershipProvider,它使用一个AccountRepository。因为MembershipProvider在MVC中是单例(据我所知),AccountRepository及其ObjectContext应该在注入一次后在MembershipProvider的整个生命周期内保持不变。

然而,在我的控制器中,我也使用带有对象上下文的存储库。在这些控制器中,我需要对象上下文在请求期间在存储库之间共享。我有以下绑定:

Bind<IMyContext>().To<MyObjectContext>().InRequestScope();
// put bindings here
Bind<IAccountRepository>().To<EFAccountRepository>

Application_Start()

kernel.Inject(Membership.Provider);

问题在于Ninject在认为请求完成后(我想是30秒后)会调用对象上下文上的dispose方法。
我的(不起作用)解决方案
我注意到当您设置绑定时,可以指定“注入到”。问题是,我需要“注入到”的“注入到”。即将对象上下文“注入”到帐户控制器中,“注入”帐户控制器时“注入”成员资格提供程序。而我好像没有那个...
我想到的解决方法(但并不太喜欢)
1. 不要在MVC中挂起MyMembershipProvider。只需向需要它的控制器传递一个实例(在接口后面),就像我与存储库一样。然后Ninject将每个请求实例化提供程序。我不喜欢它,因为我确定MVC有一个单例实例化成员身份验证提供程序的原因。 2. 查找每个请求发生的事件,并在每个事件中再次调用kernel.Inject。每个请求重新初始化提供程序几乎等同于重新实例化,除了更脏。 3. 为成员身份提供程序创建单独的帐户存储库,以便可以以不同的方式进行绑定。更改对象模型似乎不合适,因为Ninject。
结论
我认为第一个解决方法是最好的。但是,我更希望找到一种设置Ninject以按照我想要的方式进行绑定的方法。
我该怎么办?

1
我点赞是因为使用了单数人称代词。没关系,我们会把它带回来的 :) - Khanzor
1个回答

3
.InRequestScope()这一部分会导致你的一些对象被Dispose(请参见Cache and Collect)。
在提供程序的依赖项时,您需要确保不会发生此类请求范围的情况。
实现这一目标的一种方法是拥有两个绑定——一个用于请求处理分支,另一个用于全局上下文,即添加一个When...,使用context.ParentContext...链来控制是否InRequestScope()
不幸的是,我现在没有时间给出完整的答案,相关文档与代码目前不同步。

啊,原来可以更精确地指定何时注入什么。我会稍微试验一下,如果发现任何有用的东西我会回报的。 - Matthijs Wessels
@Ruben:我会记住的。如果有任何评论,我会报告它们(通过网站吧)。我对Ninject非常新,所以不要对我期望太高 :)。 - Matthijs Wessels
我卡在了如何检查作用域上。有一个返回对象的函数GetScope(),但我不知道该与什么进行比较。 - Matthijs Wessels
或者您可以在目标对象上放置一个名为“NotInRequestScope”的标记属性,然后添加一个“重复”绑定,该绑定具有WhenTargetHas<NotInRequestScope>()。 - Ruben Bartelink
感谢您的帮助,您上次的建议可能会进一步帮助我。对我们来说,这个问题已经被搁置了(现在通过一个hack解决了。我在每个请求中重新注入AccountRepository),直到下一轮迭代(从星期一开始,不用担心;))。 - Matthijs Wessels
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接