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

发布于 2024-10-31 14:34:11 字数 792 浏览 1 评论 0原文

我正在尝试使用 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 而存储库不是。

I'm trying to inject a repository to a custom membership provider with ninject in MVC 3.

In MembershipProvider I have tried the following:

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

And

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

In my ninject module i tried the following:

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

None of the above works.

When i use(in global.asa)

kernel.Inject(Membership.Provider);

together with

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

it works, but i have no life cycle management and this will cause a "ISession is open" error from NHibernate, because the ISession is InRequestScope and the repository is not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

自演自醉 2024-11-07 14:34:11

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

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

    公共类 MyMembershipProvider :SqlMembershipProvider
    {
        [注入]
        公共 SpecialUserProvider SpecialUserProvider { 获取;设置;}
        ...
    
  2. 创建一个实现 IHttpModule 的初始化器包装器,它将拉入提供程序,触发其创建:-

    公共类ProviderInitializationHttpModule:IHttpModule
    {
        公共ProviderInitializationHttpModule(MembershipProvidermembershipProvider)
        {
        }
    ...
    
  3. 在您的 中注册 IHttpModule >注册服务 :-

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

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


最后,如果您正在寻找完全脑死亡的东西来巧妙地解决它,请尝试 这个@Remo Gloor的答案


PS关于整个混乱的一篇很棒的文章是Provider 不是 @Mark Seemann 的模式。 (以及他的优秀书籍的必备插件:- .NET 中的依赖注入 这将让你弄清楚这些东西轻松地从第一原则出发)

You could use the approach @Remo Gloor outlines in his blog post on provider injection. It involves 3 steps:

  1. Add [Inject]s to any properties on your provider you need injected (although the pattern he shows -- creating a very simple class whose only function is to be a receptable for property injection and forwards any requests to a real class implemented using constructor injection -- is well worth following)

    public class MyMembershipProvider : SqlMembershipProvider
    {
        [Inject]
        public SpecialUserProvider SpecialUserProvider { get;set;}
        ...
    
  2. Create an initializer wrapper that implements IHttpModule which pulls the provider in, triggering its creation:-

    public class ProviderInitializationHttpModule : IHttpModule
    {
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider)
        {
        }
    ...
    
  3. Register the IHttpModule in your RegisterServices :-

    kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();
    
  4. there is no 4; Ninject does the rest - bootstrapping all registered IHttpModules including the one you added) during the startup sequence.

(Don't forget to read the comments on the blog post re lifetimes etc.)


Finally, if you're looking for something completely braindead direct that solves it neatly, try this @Remo Gloor answer instead


PS a great writeup on the whole mess is Provider is not a Pattern by @Mark Seemann. (and the oboligatory plug for his excellent book:- Dependency injection in .NET which will have you figuring this stuff out comfortably from first principles)

与酒说心事 2024-11-07 14:34:11

我在使用存储库的 MVC 的另一个项目中遇到了一个自定义成员资格、角色和配置文件提供程序的问题

,每当我调用该提供程序时,注入的存储库为空。

尝试调用 kernel.Inject(Membership.Provider);在 NinjectWebCommon 方法 registerServices(IKernel kernel) 中,但出现异常

结果始终为 null,因为 ASP.NET 有自己的静态属性membership.which ismembership.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);
    } 

i had this problem

a custom membership, role and profile provider in another project from MVC using repository, when ever i call the provider the injected repository was null.

tried to call kernel.Inject(Membership.Provider); in the NinjectWebCommon method registerServices(IKernel kernel) but got the exception

The result is always null, because asp.net has it's own static property for membership.which is membership.provider. and this instance is not part of instance ninject management.

so use on PostApplicationStartMethod

here is the soloution by cipto add to NinjectWebCommon the attrbute and method :

    [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);
    } 
野の 2024-11-07 14:34:11

问题在于整个成员资格基础结构是“本机”.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

The problem is that the whole Membership infrastructure is a "native" .NET code (System.Web.Security) that does not know about MVC and about the DI container used by MVC.
The static call to Membership.Provider returns the membership provider based on the configuration, however, the specified provider type is instantiated with a simple Activator.CreateInstance call. Hence, the dependency injection has no chance to kick in and set your repository dependency on the result. If you explicitly setup the returned instance with Ninject it can work, because you explicitly gave Ninject the object to set the dependencies. Even in this case it can only work with property injection and not with constructor injection, because the instance is created by the membership configuration previously.

To summarize: you cannot easily inject dependencies into the membership provider because it is not resolved from a dependency injection container.
I think you have 2 possibilities:

  1. You create a repository in the custom membership provider directly or you access it by some other means on demand (where the web context is already present).
  2. You go one level higher and check the components that would use your membership provider and you try change there (to use a membership provider resolved from your DI container instead of the uninitialized Memership.Provider). If this "higher component" is the forms authentication, then this article might be of help (using dependency injection with IFormsAuthentication and IMembershipService): http://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx
白首有我共你 2024-11-07 14:34:11

您是否尝试“手动”解析您的存储库,就像这个答案一样:
Ninject:按类型和注册名称/标识符解析对象

Did you try resolving your repository "manually", like in this answer:
Ninject : Resolving an object by type _and_ registration name/identifier
?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文