ASP.NET MVC MembershipProvider with repository and ninject
How do I communicate with the UserService through an overidden MembershipProvider class? I have no idea how to pass the connection string to the user repository inside the service.
This is how my app is structured:
Repository (constructor in the implementation takes a connection string)
public interface IUserRepository
{
IQueryable<User> GetUsers();
IQueryable<UserRole> GetUserRoles();
void InsertUser(User user);
}
Service (Constructor takes a user repository)
public interface IUserService
{
User GetUser(int userId);
User GetUser(string email);
}
UserController (An example of my controller)
public class UsersController : Controller
{
private IUserService userService;
public UsersController(IUserService userServ)
{
userService = userServ;
}
}
NinjectConfigurationModule
public class NinjectConfigurationModule : NinjectModule
{
public override void Load()
{
Bind<IUserService>().To<UserService>();
Bind<IUserRepository>().To<UserRepository>()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString
);
}
}
NinjectControllerFactory
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel kernel = new StandardKernel(new NinjectConfigurationModule());
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
// We don't want to pass null to ninject as we'll get a strange error.
return controllerType == null ? null
: (IController)kernel.Get(controllerType);
}
}
MembershipProvider (This is where my problem is)
public class SimpleMembershipProvider : MembershipProvide开发者_运维问答r
{
//How do I set up User Service here so that ninject can put my connection string here.
public override bool ValidateUser(string username, string password)
{
//Code to use user service.
}
}
Already answered question, but I think the better answer is to make the repository a property on your MembershipProvider and inject into it at Application_Start. e.g.
public class AccountMembershipProvider : MembershipProvider
{
[Inject]
public IAccountRepository AccountRepository { get; set; }
...
}
and the injection:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Inject account repository into our custom membership & role providers.
_kernel.Inject(Membership.Provider);
// Register the Object Id binder.
ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdModelBinder());
}
I've written up a more in depth explanation here:
http://www.danharman.net/2011/06/23/asp-net-mvc-3-custom-membership-provider-with-repository-injection/
You can override the MembershipProvider.Initialize function and also need some settings in web.config
public override void Initialize(string name, NameValueCollection config) {
// Validate arguments
if (config == null) throw new ArgumentNullException("config");
// Initialize base class
base.Initialize(name, config);
// Initialize current class
this.configuration = config;
System.Configuration.ConnectionStringSettings ConnectionStringSettings = System.Configuration.ConfigurationManager.ConnectionStrings[config["connectionStringName"]];
if (ConnectionStringSettings == null || ConnectionStringSettings.ConnectionString.Trim() == "") throw new ProviderException("Connection string cannot be blank.");
// then you can create a new user service using the connection string: SimpleAuthDb
}
web.config
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear/>
<add name="MyMembershipProvider"
type="Web.SimpleSqlMembershipProvider"
connectionStringName="SimpleAuthDb" />
</providers>
</membership>
I also created a custom membership provider like you. in user controller's login action will call the validateuser function like this:
Membership.ValidateUser(userName, password);
but ultimately I give up the membership provider and add a new function ValidateUser in IUserService, and then the code like this:
userService.ValidateUser(userName, password);
I think this is more simple.
精彩评论