MVC 3 ninject自定义成员资格方面处理错误 [英] MVC 3 ninject custom membership context disposed error

查看:92
本文介绍了MVC 3 ninject自定义成员资格方面处理错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用我的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:


  1. 绑定的CustomerService InSingletonScope 的成员资格提供程序本身一起。显然,这一切的长寿命EF服务通常的缺点。

  1. Bind the CustomerService as InSingletonScope 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆