I have cr开发者_运维技巧eated a custom membership provider that takes an instance of IUsersRepository in it's constructor.
private IUsersRepository usersRepository;
public CustomMembershipProvider(IUsersRepository usersRepository)
{
this.usersRepository = usersRepository;
}
This dependency is bound using Ninject
Bind<IUsersRepository>().To<SqlUsersRepository>().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString);
Bind<MembershipProvider>().To<CustomMembershipProvider>();
and used in my AccountController like so
CustomMembershipProvider provider;
public AccountController(MembershipProvider membershipProvider)
{
this.provider = (CustomMembershipProvider)membershipProvider;
}
[HttpPost]
public ActionResult Register(User user)
{
MembershipCreateStatus status = new MembershipCreateStatus();
provider.CreateUser(user.FirstName, user.LastName, user.Email, user.Password, out status);
return View(user);
}
The problem with this is that when CustomMembershipProvider is instantiated the Initialize method is not called and thus my modified Web.Config is not read.
As a side to this, I've noticed that CustomMembershipProvider is being instantiated twice - the first time as I explained above, and then again when my [HttpPost] action method is called. The second time it's instantiated using a parameterless constructor and it calls the Initialize method. I don't know what happens to the second CustomMembershipProvider as provider.CreateUser()
uses my un-Initialized CustomMembershipProvider.
I hope I've explained this well enough, any help would be appreciated.
I can't tell if you're using the Ninject.Mvc3 extension (which you probably should), but that will allow you to have a single instance of your MembershipProvider per web request. You'll have to do the binding like so:
Bind<MembershipProvider>().To<CustomMembershipProvider>().InRequestScope();
If you want to return the same instance every time you can use InSingletonScope.
Accessing web.config is not possible at the time bindings tend to be done in Mvc apps, but I usually get around that by having a custom configuration section and binding that to a method. By doing that the method will not get evaluated until the kernel is asked for a configuration section, and at that time web.config can be accessed. Something similar might work for your connection string.
Bind<MyConfigurationSection>().ToMethod(context => (MyConfigurationSection)ConfigurationManager.GetSection("mysection")).InSingletonScope();
Public Class SomeRolProvider
Inherits RoleProvider
Implements IProvider
'this service needs to get initialized
<Inject()>
Public Property _memberhip As IMemberschipService
Sub New()
'only this constructor is called
End Sub
Protected Overrides Function CreateKernel() As Ninject.IKernel
Dim modules = New NinjectModule() {New Anipmodule()}
Dim kernel = New StandardKernel(modules)
kernel.Inject(Roles.Provider)
kernel.Inject(Membership.Provider)
Return kernel
End Function
This will force the kernel to bind properties of the memberschip provider
Thanks for everybody's help on this question. I was unable to find a solution that would work well for this applications situation without the need for masses of code.
To get around the issue I looked at the default MVC 2 project and copied some of Microsoft's code. My project is probably not very testable but I needed a quick solution. I've set it up so that if I do have time to find a solution in the future, I'll be able to replace it with the current code.
精彩评论