使用Ninject将存储库注入自定义成员资格提供程序

时间:2011-04-08 14:18:01

标签: asp.net-mvc asp.net-mvc-3 ninject-2

我正在尝试使用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 is open”错误,因为ISession是InRequestScope,而存储库不是。

4 个答案:

答案 0 :(得分:5)

您可以使用@Remo Gloor outlines in his blog post on provider injection方法。它涉及3个步骤:

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

    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,包括你添加的那个。

  5. (不要忘记阅读博客帖子重生时间等的评论。)


    最后,如果你正在寻找能完全解决问题的脑道直接问题,请尝试this @Remo Gloor answer instead


    PS对整个混乱的一个很好的写作是Provider is not a Pattern by @Mark Seemann。 (以及他出色的书的代表性插件: - Dependency injection in .NET这将让你从第一原则中轻松地找出这些东西)

答案 1 :(得分:2)

我有这个问题

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

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

结果始终为null,因为asp.net拥有member.which为membership的会员自己的静态属性。并且此实例不是实例ninject管理的一部分。

所以在PostApplicationStartMethod上使用

这是 cipto 的解决方案,为NinjectWebCommon添加了attrbute和方法:

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

答案 2 :(得分: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-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx

答案 3 :(得分:0)

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

相关问题