C# 使用ninject调用初始化方法的Asp.net成员资格提供程序

C# 使用ninject调用初始化方法的Asp.net成员资格提供程序,c#,asp.net-mvc,asp.net-membership,ninject,C#,Asp.net Mvc,Asp.net Membership,Ninject,我正在尝试在asp.net mvc 4 web应用程序中使用ninject实现自定义成员资格提供程序以进行依赖项注入。这是我到目前为止的代码 public interface IAccountRepository { void Initialize(string name, NameValueCollection config); string ApplicationName { get; set; } bool ChangePassword(string usernam

我正在尝试在asp.net mvc 4 web应用程序中使用ninject实现自定义成员资格提供程序以进行依赖项注入。这是我到目前为止的代码

public interface IAccountRepository
{
    void Initialize(string name, NameValueCollection config);
    string ApplicationName { get; set; }
    bool ChangePassword(string username, string oldPassword, string newPassword);
    bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion,
        string newPasswordAnswer);
    MembershipUser CreateUser(string username, string password, string email, string passwordQuestion,
        string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);
    bool DeleteUser(string username, bool deleteAllRelatedData);
    bool EnablePasswordReset { get; }
    bool EnablePasswordRetrieval { get; }
    MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,
        out int totalRecords);
    /* I have deleted here all other methods and properties of membership for brevity */
}

这是我的ninject控制器工厂(我还在应用程序_Start()中设置了控制器工厂)

公共类NinjectControllerFactory:DefaultControllerFactory
{
私有IKernel-Ninject内核;
公共控制器工厂()
{
ninjectKernel=新的标准内核();
AddBindings();
}
受保护的重写IController GetControllerInstance(RequestContext RequestContext,类型controllerType)
{
返回controllerType==null?null:(IController)ninjectKernel.Get(controllerType);
}
私有void AddBindings()
{
ninjectKernel.Bind().To();
ninjectKernel.Bind().To();
ninjectKernel.Inject(Membership.Provider);
ninjectKernel.Inject(Roles.Provider);
}
}

正如我在AccountRepository.Initialize(name,config)时AccountMembershipProvider类中的注释中提到的;调用时,我收到以下错误:对象引用未设置为对象的实例。调试应用程序并阅读有关ninject如何工作的文章后,我无法找出问题所在。请你解释一下好吗?谢谢。

这不是您想要的答案,但我不久前自己尝试过这样做,虽然我设法找到了一种方法使其工作,但我发现解决方案过于复杂和脆弱,无法在生产中使用

我只是放弃了在我的定制提供者中使用注入的想法,因为成员资格创建提供者的方式。在我看来,这不值得让人头疼

我还认为使用注入打破了成员资格提供者的整个概念,因为其思想是提供者应该是可插拔的,并且您可以在不更改代码的情况下用另一个替换提供者。如果必须在应用程序中使用配置代码来配置数据库上下文,那么这是不可能的


好的,您可能会争辩说您不会更改提供者。。在这种情况下,为什么还要麻烦提供商呢?为什么不实现一个自定义的IIdentity和IPrincipal实现呢。

将下面的行添加到AddBindings()方法中如何

kernel.Bind().ToMethod(ctx=>Membership.Provider);
我在mvc3中使用了ninject和自定义成员资格提供程序 我不确定这是否对你有帮助,但你可以把你的和我的比较一下

[assembly: WebActivator.PreApplicationStartMethod(typeof(VBooks.Web.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(VBooks.Web.App_Start.NinjectWebCommon), "Stop")]

namespace VBooks.Web.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;

    public class ProviderInitializationHttpModule : IHttpModule
    {
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider) { }
        public void Init(HttpApplication context) { }


        void IHttpModule.Dispose()
        {

        }
    } 

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            //
            RegisterServices(kernel);

            return kernel;
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IRegisterService>().To<RegisterService>();
            kernel.Bind<IEmailService>().To<EmailService>();
            kernel.Bind<IAccountService>().To<AccountService>();
            kernel.Bind<ICoverService>().To<CoverService>();
            kernel.Bind<IAdminLogService>().To<AdminLogService>();
            kernel.Bind<MembershipProvider>().ToMethod(ctx => Membership.Provider);
            kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();

            // Add data and infrastructure modules     
            var modules = new List<INinjectModule>
            {
                new RepositoryModule()
            };

            kernel.Load(modules);

        }  

    }
}
[程序集:WebActivator.PreApplicationStartMethod(typeof(VBooks.Web.App_Start.NinjectWebCommon),“Start”)]
[程序集:WebActivator.ApplicationShutdownMethodAttribute(typeof(VBooks.Web.App_Start.NinjectWebCommon),“停止”)]
命名空间VBooks.Web.App\u开始
{
使用制度;
使用System.Web;
使用Microsoft.Web.Infrastructure.DynamicModuleHelper;
使用Ninject;
使用Ninject.Web.Common;
公共类ProviderInitializationHttpModule:IHttpModule
{
public ProviderInitializationHttpModule(MembershipProvider MembershipProvider){}
public void Init(HttpApplication上下文){}
void IHttpModule.Dispose()
{
}
} 
公共静态类NinjectWebCommon
{
私有静态只读引导程序Bootstrapper=new Bootstrapper();
/// 
///启动应用程序
/// 
公共静态void Start()
{
RegisterModule(typeof(OnePerRequestHttpModule));
RegisterModule(typeof(NinjectHttpModule));
初始化(CreateKernel);
}
/// 
///停止应用程序。
/// 
公共静态无效停止()
{
bootstrapper.ShutDown();
}
/// 
///创建将管理应用程序的内核。
/// 
///创建的内核。
私有静态IKernel CreateKernel()
{
var kernel=新的标准内核();
kernel.Bind().ToMethod(ctx=>()=>newbootstrapper().kernel);
kernel.Bind().To();
//
注册服务(内核);
返回内核;
}
/// 
///在这里加载您的模块或注册您的服务!
/// 
///内核。
私有静态无效注册服务(IKernel内核)
{
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().ToMethod(ctx=>Membership.Provider);
kernel.Bind().To();
//添加数据和基础架构模块
var模块=新列表
{
新的RepositoryModule()
};
内核加载(模块);
}  
}
}

尝试在Global.asax中初始化注册实例

公共类MVC应用程序:System.Web.HttpApplication { 受保护的无效应用程序\u Start() { RegisterAllAreas()


我在使用自定义成员资格提供程序时遇到类似问题。如果要调用AccountRepository中的initialize方法,可以执行以下操作:

使用应用程序中的ninject配置DI\u开始使用以下工具(可通过nuget获得):

公共静态类NinjectWebCommon
{
私有静态只读引导程序Bootstrapper=new Bootstrapper();
/// 
///启动应用程序
/// 
公共静态void Start()
{
RegisterModule(typeof(OnePerRequestHttpModule));
RegisterModule(typeof(NinjectHttpModule));
初始化(()=>CreateKernel());
}
/// 
///停止应用程序。
public class AccountMembershipProvider : MembershipProvider
{
    [Inject]
    public IAccountRepository AccountRepository { get; set; }

    public override void Initialize(string name, NameValueCollection config)
    {
        base.Initialize(name, config);
        AccountRepository.Initialize(name, config); 
        /* Here comes the error: Object reference not set to an instance of an object. */
    }

    public override string ApplicationName
    {
        get { return AccountRepository.ApplicationName; }
        set { AccountRepository.ApplicationName = value; }
    }

    public override bool ChangePassword(string username, string oldPassword, string newPassword)
    {
        return AccountRepository.ChangePassword(username, oldPassword, newPassword);
    }
}
public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;

    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
        AddBindings();
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);
    }

    private void AddBindings()
    {
        ninjectKernel.Bind<IAccountRepository>().To<AccountRepository>();
        ninjectKernel.Bind<IRoleRepository>().To<RoleRepository>();
        ninjectKernel.Inject(Membership.Provider);
        ninjectKernel.Inject(Roles.Provider);
    }
}
kernel.Bind<AccountMembershipProvider>().ToMethod(ctx => Membership.Provider);
[assembly: WebActivator.PreApplicationStartMethod(typeof(VBooks.Web.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(VBooks.Web.App_Start.NinjectWebCommon), "Stop")]

namespace VBooks.Web.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;

    public class ProviderInitializationHttpModule : IHttpModule
    {
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider) { }
        public void Init(HttpApplication context) { }


        void IHttpModule.Dispose()
        {

        }
    } 

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            //
            RegisterServices(kernel);

            return kernel;
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IRegisterService>().To<RegisterService>();
            kernel.Bind<IEmailService>().To<EmailService>();
            kernel.Bind<IAccountService>().To<AccountService>();
            kernel.Bind<ICoverService>().To<CoverService>();
            kernel.Bind<IAdminLogService>().To<AdminLogService>();
            kernel.Bind<MembershipProvider>().ToMethod(ctx => Membership.Provider);
            kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();

            // Add data and infrastructure modules     
            var modules = new List<INinjectModule>
            {
                new RepositoryModule()
            };

            kernel.Load(modules);

        }  

    }
}
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        // TODO register your binding here
        ...
    }
}
public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(() => CreateKernel());
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices(kernel);
        DependencyResolver.SetResolver(new NinjectServiceLocator(kernel));
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        //add your bindings here
        kernel.Bind<IAccountRepository>().To<AccountRepository>();

        kernel.Bind<MembershipProvider>().To<AccountMembershipProvider>().InRequestScope();
        kernel.Bind<RoleProvider>().To<AccountRoleProvider>().InRequestScope(); //In case you have a custom Role Provider. 

    }

}
public class AccountMembershipProvider : MembershipProvider
{
    private readonly IAccountRepository _repository;

    public AccountMembershipProvider()
    {
        _repository = ServiceLocator.Current.GetInstance<IAccountRepository>();
        _repository.Initialize();
    }

    public override bool ValidateUser(string username, string password)
    {
        return _repository.IsValidLogin(username, password);
    }

    ...//Other methods
}
public class NinjectDependencyResolver : IDependencyResolver
{
    readonly IKernel _kernel;

    public NinjectDependencyResolver()
    {
        _kernel = new StandardKernel();
        AddBindings();
    }

    public object GetService(Type serviceType)
    {
        return _kernel.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _kernel.GetAll(serviceType);
    }

    void AddBindings()
    {
        // Remember to add bindings here.
        _kernel.Bind<IAccountRepository>().To<EFAccountRepository>();
    }
}
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);

        DependencyResolver.SetResolver(new NinjectDependencyResolver()); // Here.
    }
}
public class CustomMembershipProvider : MembershipProvider
{
    private readonly IAccountRepository _repository;

    public OpenTibiaMembershipProvider()
    {
        _repository = (IAccountRepository)DependencyResolver.Current.GetService(typeof(IAccountRepository));
    }

    // Rest of implementation.
}