C# 使用ninject调用初始化方法的Asp.net成员资格提供程序
我正在尝试在asp.net mvc 4 web应用程序中使用ninject实现自定义成员资格提供程序以进行依赖项注入。这是我到目前为止的代码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
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.
}