Asp.net mvc MVC 3 ninject自定义成员身份上下文处理错误

Asp.net mvc MVC 3 ninject自定义成员身份上下文处理错误,asp.net-mvc,ninject,membership,Asp.net Mvc,Ninject,Membership,我有一个自定义成员资格,它首先使用EF代码(4.1)使用我的CustomerService与数据库通信 我使用ninject将CustomerService注入到我的自定义成员类中。 但是当我尝试验证时,我得到了一个上下文处理错误。 这是因为在ninject my上下文中,存储库和服务位于RequestScope()中。 因为我在自定义成员身份的属性上使用[inject]注入CustomerService,在ninject中使用_kernel.inject(membership.Provider

我有一个自定义成员资格,它首先使用EF代码(4.1)使用我的CustomerService与数据库通信 我使用ninject将CustomerService注入到我的自定义成员类中。 但是当我尝试验证时,我得到了一个上下文处理错误。 这是因为在ninject my上下文中,存储库和服务位于RequestScope()中。 因为我在自定义成员身份的属性上使用[inject]注入CustomerService,在ninject中使用_kernel.inject(membership.Provider),所以它只在启动时注入

我读了很多关于这个问题的帖子,但找不到解决这个问题的答案


有人能解决这个问题吗

对于刚开始使用DI和IoC容器的人来说,这是一个常见的错误。您必须保持作用域的一致性。当依赖于请求范围的服务绑定到单例范围时,不能将依赖项绑定到请求范围(或者更糟糕的是,有些范围根本不由容器管理)。这完全是错误的

这里有两个基本选项:

  • CustomerService
    绑定为
    InSingletonScope
    以及成员资格提供程序本身。显然,这具有长寿命EF服务的所有常见缺点

  • 不要让您的会员资格提供商依赖于
    CustomerService
    实例。相反,将依赖关系设置为
    CustomerServiceFactory
    ,该工厂可以创建
    CustomerService
    实例,并将对成员资格提供程序的每次调用都视为暂时的

  • 对于#2,创建和绑定工厂的过程非常简单:

    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>();
        }
    }
    

    这实际上非常有效,因为服务本身仍然是请求范围,但是工厂(以及成员资格提供者)在每个请求期间只会获得不同的实例。不仅如此,成员资格提供程序还保证(通过工厂)获得相同的实例,无论在单个请求期间调用多少个成员资格方法。因此,尽管必须集成到遗留代码中,您仍然可以获得DI的几乎所有好处。

    对于刚开始使用DI和IoC容器的人来说,这是一个常见的错误。您必须保持作用域的一致性。当依赖于请求范围的服务绑定到单例范围时,不能将依赖项绑定到请求范围(或者更糟糕的是,有些范围根本不由容器管理)。这完全是错误的

    这里有两个基本选项:

  • CustomerService
    绑定为
    InSingletonScope
    以及成员资格提供程序本身。显然,这具有长寿命EF服务的所有常见缺点

  • 不要让您的会员资格提供商依赖于
    CustomerService
    实例。相反,将依赖关系设置为
    CustomerServiceFactory
    ,该工厂可以创建
    CustomerService
    实例,并将对成员资格提供程序的每次调用都视为暂时的

  • 对于#2,创建和绑定工厂的过程非常简单:

    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>();
        }
    }
    

    这实际上非常有效,因为服务本身仍然是请求范围,但是工厂(以及成员资格提供者)在每个请求期间只会获得不同的实例。不仅如此,成员资格提供程序还保证(通过工厂)获得相同的实例,无论在单个请求期间调用多少个成员资格方法。所以,尽管必须集成到遗留代码中,但您几乎获得了DI的所有好处。

    我觉得很愚蠢,在浏览ninject没有将属性注入我的Membership提供程序时,我甚至没有阅读这个问题,我实现了其他问题的解决方案。。。当然,它仍然没有注入资产。而且我不能在成员资格提供程序中使用构造函数injection…感觉很愚蠢,我甚至在浏览ninject没有在我的Memebership提供程序中注入属性的问题时没有阅读该问题,我实现了其他问题的解决方案。。。当然,它仍然没有注入资产。我不能在成员资格提供程序中使用构造函数导入。。。
    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; }
    }