c# - How do I stop a custom EF-based RoleProvider from caching results? -
i have asp.net mvc 4 application required use pre-existing membership model of users/roles. way did implement custom asp.net roleprovider manage access, uses entity framework repositories read user data database. method read user roles shown below, method implementations follow pattern:
public class ourroleprovider : roleprovider { private iuserrepository _userrepository; public ourroleprovider() : this(container.resolve<iuserrepository>()) { } public ourroleprovider(iuserrepository userrepository) { _userrepository = userrepository; } public override string[] getrolesforuser(string username) { var user = _userrepository.getuserbyusername(username); if (user.roles.isnullorempty()) return new string[0]; return user.roles.select(r => r.rolename).toarray(); } }
i have come across problem described in post. because single instance of roleprovider re-used lifetime of application, , other functionality creates it's own per-request dbcontext persist data, changes made user profile not reflected roleprovider until restart in application, because it's underlying dbcontext not being refreshed. means can remove user role, , still have access role's functionality until app restart.
i have tried creating new repository instance within roleprovider methods, i.e. in getroleforuser():
var user = _userrepository.getuserbyusername(username);
becomes
var userrepository = container.resolve<iuserrepository>(); var user = userrepository.getuserbyusername(username);
this fixes issue breaks unit tests don't use di container , inject mock repository via constructor. there lot of unit tests re-write.
i'd stick custom roleprovider if possible make use of features such authorize
atrribute. need re-instantiate roleprovider on per-request basis or force ef repository update database. far haven't found way this. possible? or there better solution?
you shouldn't define ef services' life time singleton (it should per-request
life time). because dbcontext not thread safe , it's designed have short life. activating caching of role provider done somewhere else, in web.config file:
<rolemanager defaultprovider="customroleprovider" cacherolesincookie="true" enabled="true"> <providers> <clear /> <add name="customroleprovider" type="security.customroleprovider" /> </providers> </rolemanager>
the above custom role provider cached, beacuse it's using cacherolesincookie="true" here.
Comments
Post a Comment