18

我正在尝试使用 MVC 3 中的 ninject 将存储库注入自定义成员资格提供程序。

在 MembershipProvider 我尝试了以下方法:

[Inject]
public ICustomerRepository _customerRepository{ get; set; }

[Inject]
public TUMembershipProvider(ICustomerRepository customerRepository)
{
    _customerRepository = customerRepository;
}

在我的 ninject 模块中,我尝试了以下操作:

Bind<MembershipProvider>().ToConstant(Membership.Provider);

以上都不起作用。

当我使用(在 global.asa 中)

kernel.Inject(Membership.Provider);

和...一起

[Inject]
public ICustomerRepository _customerRepository{ get; set; }

它可以工作,但是我没有生命周期管理,这将导致 NHibernate 出现“ISession 已打开”错误,因为 ISession 是 InRequestScope 而存储库不是。

4

4 回答 4

5

您可以使用@Remo Gloor 在他关于提供程序注入的博客文章中概述的方法。它涉及3个步骤:

  1. [Inject]s 添加到您需要注入的提供程序上的任何属性(尽管他展示的模式 - 创建一个非常简单的类,其唯一功能是接受属性注入并将任何请求转发到使用构造函数注入实现的真实类 - 是非常值得关注)

    public class MyMembershipProvider : SqlMembershipProvider
    {
        [Inject]
        public SpecialUserProvider SpecialUserProvider { get;set;}
        ...
    
  2. 创建一个初始化包装器,该包装器实现IHttpModule将提供者拉入其中,触发其创建:-

    public class ProviderInitializationHttpModule : IHttpModule
    {
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider)
        {
        }
    ...
    
  3. IHttpModule在您的注册RegisterServices:-

    kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();
    
  4. 没有4;Ninject 会在启动序列期间完成其余的工作 - 引导所有已注册IHttpModules的,包括您添加的)。

(不要忘记阅读博客文章重新生命周期等的评论。)


最后,如果您正在寻找可以巧妙解决问题的完全无脑直接的东西,请尝试使用此@Remo Gloor 答案


PS 一篇关于整个混乱的精彩文章是Provider is not a Pattern by @Mark Seemann。(以及他出色著作的必备插件:- .NET 中的依赖注入,这将使您从第一原则中轻松地弄清楚这些东西)

于 2012-05-01T07:34:11.163 回答
2

我有这个问题

使用存储库的 MVC 的另一个项目中的自定义成员资格、角色和配置文件提供程序,当我调用提供程序时,注入的存储库为空。

试图调用 kernel.Inject(Membership.Provider); 在 NinjectWebCommon 方法 registerServices(IKernel kernel) 但得到了异常

结果总是空的,因为 asp.net 有它自己的 members 的静态属性。它是 members.provider。并且此实例不是实例 ninject 管理的一部分。

所以在 PostApplicationStartMethod 上使用

这是cipto添加到 NinjectWebCommon 属性和方法的解决方案:

    [assembly: WebActivator.PreApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "Start")]
    [assembly: WebActivator.PostApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "RegisterMembership")]
    [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebApp.App_Start.NinjectWebCommon), "Stop")]

    public static void RegisterMembership()
    {
        bootstrapper.Kernel.Inject(Membership.Provider);
    } 
于 2013-04-20T14:40:10.673 回答
1

问题在于,整个 Membership 基础结构是一个“本机”.NET 代码 (System.Web.Security),它不了解 MVC 和 MVC 使用的 DI 容器。对 Membership.Provider 的静态调用会根据配置返回成员资格提供程序,但是,指定的提供程序类型是通过简单的 Activator.CreateInstance 调用来实例化的。因此,依赖注入没有机会启动并设置您对结果的存储库依赖。如果你用 Ninject 显式设置返回的实例,它可以工作,因为你显式地给了 Ninject 对象来设置依赖关系。即使在这种情况下,它也只能与属性注入一起使用,而不能与构造函数注入一起使用,因为实例是由先前的成员资格配置创建的。

总结一下:您不能轻易地将依赖项注入到成员资格提供程序中,因为它不是从依赖项注入容器中解析出来的。我认为你有两种可能性:

  1. 您可以直接在自定义成员资格提供程序中创建存储库,或者通过其他方式按需访问它(其中 Web 上下文已经存在)。
  2. 您上一层并检查将使用您的成员资格提供程序的组件,然后尝试在那里进行更改(使用从您的 DI 容器解析的成员资格提供程序,而不是未初始化的 Memership.Provider)。如果这个“更高的组件”是表单身份验证,那么这篇文章可能会有所帮助(使用 IFormsAuthentication 和 IMembershipService 的依赖注入):http ://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-依赖注入-in-asp-net-mvc-nerddinner-com-application.aspx
于 2011-06-05T21:07:48.480 回答
0

您是否尝试过“手动”解析您的存储库,就像在这个答案中一样: Ninject : Resolving an object by type _and_registration name/identifier

于 2011-06-13T19:07:02.450 回答