MVC 3 ninject自定义成员资格方面处理错误 [英] MVC 3 ninject custom membership context disposed error
问题描述
我有一个使用我的CustomerService自定义成员资格使用EF code先与数据库进行通信(4.1)
我用ninject到的CustomerService注入到我的自定义成员资格类。
但是,当我尝试验证我得到一个上下文处理错误。
这是因为在ninject我的情况下,库和服务InRequestScope()。
因为我用注入[注]在我的自定义成员资格的属性和ninject使用的CustomerService的_kernel.Inject(Membership.Provider),它只是在注射启动的。
I have a custom membership that uses my CustomerService to communicate with the database using EF code first (4.1) I use ninject to inject the CustomerService into my custom membership class. But when I try to validate I get a context disposed error. This is because in ninject my context, repositories and services are InRequestScope(). And because I inject the CustomerService using [inject] on a property of my custom membership and in ninject use the _kernel.Inject(Membership.Provider), it is only injected ones on startup.
我读了很多关于这个问题的帖子,但无法找到修复此问题的答案。
I read a lot of posts about this problem but can not find an answer that fixes this problem.
有没有人有一个解决的办法?
Does anyone have a solution to this?
推荐答案
这是谁正在开始接触DI和IoC容器中,人们常犯的错误。你必须保持范围的一致性。您的不能的绑定到时依赖于它们的服务绑定到独居范围请求范围依赖(或者更糟的是,有一些没有范围由容器在所有的管理)。这是完全错误的。
This is a common mistake for people who are starting out with DI and IoC containers. You have to maintain consistency of scopes. You cannot have dependencies bound to a request scope when the services that depend on them are bound to singleton scope (or worse, have some scope not managed by the container at all). It's simply wrong.
您有两种基本选择在这里:
You have two basic options here:
-
绑定
的CustomerService
为InSingletonScope
的成员资格提供程序本身一起。显然,这一切的长寿命EF服务通常的缺点。
Bind the
CustomerService
asInSingletonScope
along with the membership provider itself. Obviously, this has all of the usual drawbacks of long-lived EF services.
不要有你的会员供应商依赖于的CustomerService
实例。相反,要对相关性的 CustomerServiceFactory
可的创建的的CustomerService
情况下,把每调用成员资格提供瞬态。
Don't have your membership provider depend on the CustomerService
instance. Instead, make the dependency on a CustomerServiceFactory
which can create CustomerService
instances, and treat every call to the membership provider as transient.
有关#2,创建和绑定一个工厂的过程非常简单:
For #2, the process of creating and binding a factory is very simple:
public interface ICustomerServiceFactory
{
ICustomerService GetService();
}
public class NinjectCustomerServiceFactory : ICustomerServiceFactory
{
private readonly IKernel kernel;
public NinjectCustomerServiceFactory(IKernel kernel)
{
if (kernel == null)
throw new ArgumentNullException("kernel");
this.kernel = kernel;
}
public ICustomerService GetService()
{
return kernel.Get<ICustomerService>();
}
}
那么你的模块中:
Then in your module:
Bind<ICustomerService>()
.To<EFCustomerService>();
.InRequestScope();
Bind<ICustomerServiceFactory>()
.To<NinjectCustomerServiceFactory>()
.InSingletonScope();
请注意作用域在这里。该服务本身仍然是请求范围,但工厂是单身,这是同一范围内的提供者。此工作,因为工厂直接进到内核,这也是单(或多或少)。
Note the scopes here. The service itself is still request-scoped, but the factory is singleton, which is the same scope as the provider. This works because the factory goes directly to the kernel, which is also singleton (more or less).
您想最终凭会员code看起来像这样:
You'd end up with membership code looking like so:
public class MyMembershipProvider : MembershipProvider
{
public override MembershipUserCollection GetAllUsers()
{
var service = serviceFactory.GetService();
var serviceUsers = service.GetAllUsers();
return serviceUsers.Select(u => CreateMembershipUser(u));
}
// Other methods...
[Inject]
public ICustomerServiceFactory ServiceFactory { get; set; }
}
这实际上工作得非常好,因为服务本身仍然是在请求范围内,但工厂(和成员资格提供)每个请求中只会得到一个不同的实例。不仅如此,但成员资格提供保证获得的相同的实例(通过工厂),无论会员的方法有多少单个请求中调用。所以,你得到的DI几乎所有的好处,尽管其融入传统code的。
This actually works very well because the service itself will still be request-scoped, but the factory (and thus the membership provider) will just get a different instance during each request. Not only that but the membership provider is guaranteed to get the same instance (through the factory) no matter how many membership methods are called during a single request. So you're getting almost all the benefits of DI, in spite of having to integrate into legacy code.
这篇关于MVC 3 ninject自定义成员资格方面处理错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!