ASP.NET Identity 2.0 UserManager alongside with UnitOfWork and Service-Locator anti-pattern

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite
2












I was wondering whether it is a good aproach to have Identity 2.0 UserManager next to UnitOfWork pattern? I am using UserManager only in login and register as it gives freedom of not taking care of password hashing (also provides options to email user etc.) and user-to-role management. Although for the rest of the project I am using UOW to maintain users and roles (e.g. to edit user information (not password).



These are my Login and Registermethods:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult >Login(UserLoginViewModel model, string returnUrl)
u.UstId == model.Login)).FirstOrDefault();
if (user == null)

this.ModelState.AddModelError("Login", Properties.Error.UserDoesntExist);
return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;

if (!await userManager.CheckPasswordAsync(user, model.Password))

this.ModelState.AddModelError("Password", Properties.Error.WrongPassword);
return this.View();


var ident = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authManager.SignIn(new AuthenticationProperties IsPersistent = false , ident);

this.TempData["SuccessMessage"] = "Logged in";
if (!string.IsNullOrEmpty(returnUrl) && this.Url.IsLocalUrl(returnUrl))

return this.Redirect(returnUrl);

return this.RedirectToAction("Index");


[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(UserRegisterViewModel model)

if (!this.ModelState.IsValid)

return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

var user = new User(model);
var result = userManager.Create(user, model.Password);
if (!result.Succeeded)

result.Errors.ForEach(e => this.ModelState.AddModelError(string.Empty, e));
return this.View();


var userRole = this.unitOfWork.UserRoleRepository.Find(ur => ur.Name == "User").Result.FirstOrDefault();
if (userRole == null)

userRole = new UserRole("User");

this.unitOfWork.UserRoleRepository.Add(userRole);
this.unitOfWork.Complete();

userManager.AddToRole(user.Id, "User");

this.TempData["SuccessMessage"] = "Registered";
return this.RedirectToAction("Index");



And assigning user to role also uses UserManager:



[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Assign(AssignRoleViewModel model)

if (!this.ModelState.IsValid)

return this.View(model);

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

userManager.RemoveFromRoles(model.Id, userManager.GetRoles(model.Id).ToArray());
if (model.SelectedRoles.Any())

userManager.AddToRoles(model.Id, model.SelectedRoles.ToArray());

return this.RedirectToAction("Details", new id = model.Id );



Although Edit method uses uow:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)

if (this.ModelState.IsValid)

var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = this.unitOfWork.UserRepository.GetAll().Result;
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



And my UserManager:



public class LeaveUserManager : UserManager<User>

public LeaveUserManager(IUserStore<User> store) : base(store)



public static LeaveUserManager Create(
IdentityFactoryOptions<LeaveUserManager> options, IOwinContext context)

var manager = new LeaveUserManager(
new UserStore<User>(context.Get<VacationsContext>()))

EmailService = new LeaveEmailService()
;
return manager;




Is it OK to leave it like this or I should create my own userManager which will be using uow and repositories?

I am using ASP.NET MVC5 with EF6.




2018-03-20 edit:

I have removed .Result from all async methods and replaced with await.

I have dependency injected all managers, dbcontext and uow using Ninject library.



 private static void RegisterService(IKernel kernel)

kernel.Bind<VacationsContext>().ToSelf().InSingletonScope();
kernel.Bind<RoleManager<UserRole>>().ToSelf().InRequestScope();
kernel.Bind<LeaveUserManager>().ToMethod(c => LeaveUserManager.Create(kernel.Get<VacationsContext>())).InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod(c => HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
kernel.Bind<IUserStore<User>>().To<UserStore<User>>().InRequestScope().WithConstructorArgument("context", kernel.Get<VacationsContext>());
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();



Injection works in controllers:



public HomeController(LeaveUserManager userManager, IAuthenticationManager authManager, IUnitOfWork unitOfWork)

this.leaveUserManager = userManager;
this.authenticationManager = authManager;
this.unitOfWork = unitOfWork;



And if noone says that it is some kind of violation - then I will leave LeaveUserManager as it is - using it's own way to database access layer (skipping my custom uow).







share|improve this question





















  • UserManager is more of an implementation concern that you can encapsulate behind your own abstraction in whatever structure/pattern you want.
    – Nkosi
    Mar 19 at 16:58






  • 1




    Avoid .Result within async methods as those blocking calls can lead to deadlocks
    – Nkosi
    Mar 19 at 17:34










  • you should post edits to your code as a new question(review request) so that you can get more feedback.
    – Malachi♦
    Mar 20 at 13:12










  • @Malachi, I think that this is now pretty clear for me, but maybe it would be a good idea to modify question title that this also references to DI and Service Locator anti-pattern. Morelike for others than for me, what do you think?
    – Marek Czaplicki
    Mar 20 at 13:30










  • Oh, I see you didn't actually show the changes you made just added other code pertinent to the review. You did good. As you were...lol
    – Malachi♦
    Mar 20 at 13:32
















up vote
1
down vote

favorite
2












I was wondering whether it is a good aproach to have Identity 2.0 UserManager next to UnitOfWork pattern? I am using UserManager only in login and register as it gives freedom of not taking care of password hashing (also provides options to email user etc.) and user-to-role management. Although for the rest of the project I am using UOW to maintain users and roles (e.g. to edit user information (not password).



These are my Login and Registermethods:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult >Login(UserLoginViewModel model, string returnUrl)
u.UstId == model.Login)).FirstOrDefault();
if (user == null)

this.ModelState.AddModelError("Login", Properties.Error.UserDoesntExist);
return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;

if (!await userManager.CheckPasswordAsync(user, model.Password))

this.ModelState.AddModelError("Password", Properties.Error.WrongPassword);
return this.View();


var ident = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authManager.SignIn(new AuthenticationProperties IsPersistent = false , ident);

this.TempData["SuccessMessage"] = "Logged in";
if (!string.IsNullOrEmpty(returnUrl) && this.Url.IsLocalUrl(returnUrl))

return this.Redirect(returnUrl);

return this.RedirectToAction("Index");


[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(UserRegisterViewModel model)

if (!this.ModelState.IsValid)

return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

var user = new User(model);
var result = userManager.Create(user, model.Password);
if (!result.Succeeded)

result.Errors.ForEach(e => this.ModelState.AddModelError(string.Empty, e));
return this.View();


var userRole = this.unitOfWork.UserRoleRepository.Find(ur => ur.Name == "User").Result.FirstOrDefault();
if (userRole == null)

userRole = new UserRole("User");

this.unitOfWork.UserRoleRepository.Add(userRole);
this.unitOfWork.Complete();

userManager.AddToRole(user.Id, "User");

this.TempData["SuccessMessage"] = "Registered";
return this.RedirectToAction("Index");



And assigning user to role also uses UserManager:



[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Assign(AssignRoleViewModel model)

if (!this.ModelState.IsValid)

return this.View(model);

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

userManager.RemoveFromRoles(model.Id, userManager.GetRoles(model.Id).ToArray());
if (model.SelectedRoles.Any())

userManager.AddToRoles(model.Id, model.SelectedRoles.ToArray());

return this.RedirectToAction("Details", new id = model.Id );



Although Edit method uses uow:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)

if (this.ModelState.IsValid)

var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = this.unitOfWork.UserRepository.GetAll().Result;
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



And my UserManager:



public class LeaveUserManager : UserManager<User>

public LeaveUserManager(IUserStore<User> store) : base(store)



public static LeaveUserManager Create(
IdentityFactoryOptions<LeaveUserManager> options, IOwinContext context)

var manager = new LeaveUserManager(
new UserStore<User>(context.Get<VacationsContext>()))

EmailService = new LeaveEmailService()
;
return manager;




Is it OK to leave it like this or I should create my own userManager which will be using uow and repositories?

I am using ASP.NET MVC5 with EF6.




2018-03-20 edit:

I have removed .Result from all async methods and replaced with await.

I have dependency injected all managers, dbcontext and uow using Ninject library.



 private static void RegisterService(IKernel kernel)

kernel.Bind<VacationsContext>().ToSelf().InSingletonScope();
kernel.Bind<RoleManager<UserRole>>().ToSelf().InRequestScope();
kernel.Bind<LeaveUserManager>().ToMethod(c => LeaveUserManager.Create(kernel.Get<VacationsContext>())).InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod(c => HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
kernel.Bind<IUserStore<User>>().To<UserStore<User>>().InRequestScope().WithConstructorArgument("context", kernel.Get<VacationsContext>());
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();



Injection works in controllers:



public HomeController(LeaveUserManager userManager, IAuthenticationManager authManager, IUnitOfWork unitOfWork)

this.leaveUserManager = userManager;
this.authenticationManager = authManager;
this.unitOfWork = unitOfWork;



And if noone says that it is some kind of violation - then I will leave LeaveUserManager as it is - using it's own way to database access layer (skipping my custom uow).







share|improve this question





















  • UserManager is more of an implementation concern that you can encapsulate behind your own abstraction in whatever structure/pattern you want.
    – Nkosi
    Mar 19 at 16:58






  • 1




    Avoid .Result within async methods as those blocking calls can lead to deadlocks
    – Nkosi
    Mar 19 at 17:34










  • you should post edits to your code as a new question(review request) so that you can get more feedback.
    – Malachi♦
    Mar 20 at 13:12










  • @Malachi, I think that this is now pretty clear for me, but maybe it would be a good idea to modify question title that this also references to DI and Service Locator anti-pattern. Morelike for others than for me, what do you think?
    – Marek Czaplicki
    Mar 20 at 13:30










  • Oh, I see you didn't actually show the changes you made just added other code pertinent to the review. You did good. As you were...lol
    – Malachi♦
    Mar 20 at 13:32












up vote
1
down vote

favorite
2









up vote
1
down vote

favorite
2






2





I was wondering whether it is a good aproach to have Identity 2.0 UserManager next to UnitOfWork pattern? I am using UserManager only in login and register as it gives freedom of not taking care of password hashing (also provides options to email user etc.) and user-to-role management. Although for the rest of the project I am using UOW to maintain users and roles (e.g. to edit user information (not password).



These are my Login and Registermethods:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult >Login(UserLoginViewModel model, string returnUrl)
u.UstId == model.Login)).FirstOrDefault();
if (user == null)

this.ModelState.AddModelError("Login", Properties.Error.UserDoesntExist);
return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;

if (!await userManager.CheckPasswordAsync(user, model.Password))

this.ModelState.AddModelError("Password", Properties.Error.WrongPassword);
return this.View();


var ident = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authManager.SignIn(new AuthenticationProperties IsPersistent = false , ident);

this.TempData["SuccessMessage"] = "Logged in";
if (!string.IsNullOrEmpty(returnUrl) && this.Url.IsLocalUrl(returnUrl))

return this.Redirect(returnUrl);

return this.RedirectToAction("Index");


[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(UserRegisterViewModel model)

if (!this.ModelState.IsValid)

return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

var user = new User(model);
var result = userManager.Create(user, model.Password);
if (!result.Succeeded)

result.Errors.ForEach(e => this.ModelState.AddModelError(string.Empty, e));
return this.View();


var userRole = this.unitOfWork.UserRoleRepository.Find(ur => ur.Name == "User").Result.FirstOrDefault();
if (userRole == null)

userRole = new UserRole("User");

this.unitOfWork.UserRoleRepository.Add(userRole);
this.unitOfWork.Complete();

userManager.AddToRole(user.Id, "User");

this.TempData["SuccessMessage"] = "Registered";
return this.RedirectToAction("Index");



And assigning user to role also uses UserManager:



[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Assign(AssignRoleViewModel model)

if (!this.ModelState.IsValid)

return this.View(model);

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

userManager.RemoveFromRoles(model.Id, userManager.GetRoles(model.Id).ToArray());
if (model.SelectedRoles.Any())

userManager.AddToRoles(model.Id, model.SelectedRoles.ToArray());

return this.RedirectToAction("Details", new id = model.Id );



Although Edit method uses uow:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)

if (this.ModelState.IsValid)

var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = this.unitOfWork.UserRepository.GetAll().Result;
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



And my UserManager:



public class LeaveUserManager : UserManager<User>

public LeaveUserManager(IUserStore<User> store) : base(store)



public static LeaveUserManager Create(
IdentityFactoryOptions<LeaveUserManager> options, IOwinContext context)

var manager = new LeaveUserManager(
new UserStore<User>(context.Get<VacationsContext>()))

EmailService = new LeaveEmailService()
;
return manager;




Is it OK to leave it like this or I should create my own userManager which will be using uow and repositories?

I am using ASP.NET MVC5 with EF6.




2018-03-20 edit:

I have removed .Result from all async methods and replaced with await.

I have dependency injected all managers, dbcontext and uow using Ninject library.



 private static void RegisterService(IKernel kernel)

kernel.Bind<VacationsContext>().ToSelf().InSingletonScope();
kernel.Bind<RoleManager<UserRole>>().ToSelf().InRequestScope();
kernel.Bind<LeaveUserManager>().ToMethod(c => LeaveUserManager.Create(kernel.Get<VacationsContext>())).InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod(c => HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
kernel.Bind<IUserStore<User>>().To<UserStore<User>>().InRequestScope().WithConstructorArgument("context", kernel.Get<VacationsContext>());
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();



Injection works in controllers:



public HomeController(LeaveUserManager userManager, IAuthenticationManager authManager, IUnitOfWork unitOfWork)

this.leaveUserManager = userManager;
this.authenticationManager = authManager;
this.unitOfWork = unitOfWork;



And if noone says that it is some kind of violation - then I will leave LeaveUserManager as it is - using it's own way to database access layer (skipping my custom uow).







share|improve this question













I was wondering whether it is a good aproach to have Identity 2.0 UserManager next to UnitOfWork pattern? I am using UserManager only in login and register as it gives freedom of not taking care of password hashing (also provides options to email user etc.) and user-to-role management. Although for the rest of the project I am using UOW to maintain users and roles (e.g. to edit user information (not password).



These are my Login and Registermethods:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult >Login(UserLoginViewModel model, string returnUrl)
u.UstId == model.Login)).FirstOrDefault();
if (user == null)

this.ModelState.AddModelError("Login", Properties.Error.UserDoesntExist);
return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;

if (!await userManager.CheckPasswordAsync(user, model.Password))

this.ModelState.AddModelError("Password", Properties.Error.WrongPassword);
return this.View();


var ident = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authManager.SignIn(new AuthenticationProperties IsPersistent = false , ident);

this.TempData["SuccessMessage"] = "Logged in";
if (!string.IsNullOrEmpty(returnUrl) && this.Url.IsLocalUrl(returnUrl))

return this.Redirect(returnUrl);

return this.RedirectToAction("Index");


[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(UserRegisterViewModel model)

if (!this.ModelState.IsValid)

return this.View();

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

var user = new User(model);
var result = userManager.Create(user, model.Password);
if (!result.Succeeded)

result.Errors.ForEach(e => this.ModelState.AddModelError(string.Empty, e));
return this.View();


var userRole = this.unitOfWork.UserRoleRepository.Find(ur => ur.Name == "User").Result.FirstOrDefault();
if (userRole == null)

userRole = new UserRole("User");

this.unitOfWork.UserRoleRepository.Add(userRole);
this.unitOfWork.Complete();

userManager.AddToRole(user.Id, "User");

this.TempData["SuccessMessage"] = "Registered";
return this.RedirectToAction("Index");



And assigning user to role also uses UserManager:



[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Assign(AssignRoleViewModel model)

if (!this.ModelState.IsValid)

return this.View(model);

var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();

userManager.RemoveFromRoles(model.Id, userManager.GetRoles(model.Id).ToArray());
if (model.SelectedRoles.Any())

userManager.AddToRoles(model.Id, model.SelectedRoles.ToArray());

return this.RedirectToAction("Details", new id = model.Id );



Although Edit method uses uow:



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)

if (this.ModelState.IsValid)

var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = this.unitOfWork.UserRepository.GetAll().Result;
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



And my UserManager:



public class LeaveUserManager : UserManager<User>

public LeaveUserManager(IUserStore<User> store) : base(store)



public static LeaveUserManager Create(
IdentityFactoryOptions<LeaveUserManager> options, IOwinContext context)

var manager = new LeaveUserManager(
new UserStore<User>(context.Get<VacationsContext>()))

EmailService = new LeaveEmailService()
;
return manager;




Is it OK to leave it like this or I should create my own userManager which will be using uow and repositories?

I am using ASP.NET MVC5 with EF6.




2018-03-20 edit:

I have removed .Result from all async methods and replaced with await.

I have dependency injected all managers, dbcontext and uow using Ninject library.



 private static void RegisterService(IKernel kernel)

kernel.Bind<VacationsContext>().ToSelf().InSingletonScope();
kernel.Bind<RoleManager<UserRole>>().ToSelf().InRequestScope();
kernel.Bind<LeaveUserManager>().ToMethod(c => LeaveUserManager.Create(kernel.Get<VacationsContext>())).InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod(c => HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
kernel.Bind<IUserStore<User>>().To<UserStore<User>>().InRequestScope().WithConstructorArgument("context", kernel.Get<VacationsContext>());
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();



Injection works in controllers:



public HomeController(LeaveUserManager userManager, IAuthenticationManager authManager, IUnitOfWork unitOfWork)

this.leaveUserManager = userManager;
this.authenticationManager = authManager;
this.unitOfWork = unitOfWork;



And if noone says that it is some kind of violation - then I will leave LeaveUserManager as it is - using it's own way to database access layer (skipping my custom uow).









share|improve this question












share|improve this question




share|improve this question








edited Mar 21 at 21:10
























asked Mar 19 at 14:17









Marek Czaplicki

1235




1235











  • UserManager is more of an implementation concern that you can encapsulate behind your own abstraction in whatever structure/pattern you want.
    – Nkosi
    Mar 19 at 16:58






  • 1




    Avoid .Result within async methods as those blocking calls can lead to deadlocks
    – Nkosi
    Mar 19 at 17:34










  • you should post edits to your code as a new question(review request) so that you can get more feedback.
    – Malachi♦
    Mar 20 at 13:12










  • @Malachi, I think that this is now pretty clear for me, but maybe it would be a good idea to modify question title that this also references to DI and Service Locator anti-pattern. Morelike for others than for me, what do you think?
    – Marek Czaplicki
    Mar 20 at 13:30










  • Oh, I see you didn't actually show the changes you made just added other code pertinent to the review. You did good. As you were...lol
    – Malachi♦
    Mar 20 at 13:32
















  • UserManager is more of an implementation concern that you can encapsulate behind your own abstraction in whatever structure/pattern you want.
    – Nkosi
    Mar 19 at 16:58






  • 1




    Avoid .Result within async methods as those blocking calls can lead to deadlocks
    – Nkosi
    Mar 19 at 17:34










  • you should post edits to your code as a new question(review request) so that you can get more feedback.
    – Malachi♦
    Mar 20 at 13:12










  • @Malachi, I think that this is now pretty clear for me, but maybe it would be a good idea to modify question title that this also references to DI and Service Locator anti-pattern. Morelike for others than for me, what do you think?
    – Marek Czaplicki
    Mar 20 at 13:30










  • Oh, I see you didn't actually show the changes you made just added other code pertinent to the review. You did good. As you were...lol
    – Malachi♦
    Mar 20 at 13:32















UserManager is more of an implementation concern that you can encapsulate behind your own abstraction in whatever structure/pattern you want.
– Nkosi
Mar 19 at 16:58




UserManager is more of an implementation concern that you can encapsulate behind your own abstraction in whatever structure/pattern you want.
– Nkosi
Mar 19 at 16:58




1




1




Avoid .Result within async methods as those blocking calls can lead to deadlocks
– Nkosi
Mar 19 at 17:34




Avoid .Result within async methods as those blocking calls can lead to deadlocks
– Nkosi
Mar 19 at 17:34












you should post edits to your code as a new question(review request) so that you can get more feedback.
– Malachi♦
Mar 20 at 13:12




you should post edits to your code as a new question(review request) so that you can get more feedback.
– Malachi♦
Mar 20 at 13:12












@Malachi, I think that this is now pretty clear for me, but maybe it would be a good idea to modify question title that this also references to DI and Service Locator anti-pattern. Morelike for others than for me, what do you think?
– Marek Czaplicki
Mar 20 at 13:30




@Malachi, I think that this is now pretty clear for me, but maybe it would be a good idea to modify question title that this also references to DI and Service Locator anti-pattern. Morelike for others than for me, what do you think?
– Marek Czaplicki
Mar 20 at 13:30












Oh, I see you didn't actually show the changes you made just added other code pertinent to the review. You did good. As you were...lol
– Malachi♦
Mar 20 at 13:32




Oh, I see you didn't actually show the changes you made just added other code pertinent to the review. You did good. As you were...lol
– Malachi♦
Mar 20 at 13:32










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










First, avoid .Result within async methods



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
//...

var userList = this.unitOfWork.UserRepository.GetAll().Result;

//...



as those blocking calls can lead to deadlocks. Make the function async all the way through



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
if (this.ModelState.IsValid)
var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = await this.unitOfWork.UserRepository.GetAll();
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



Next, it appears that DI and service locator is being mixed.



var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;


could be seen as a service locator anti-pattern within the action being called.



Assuming the unitOfWork is being injected into the controller then user manager and authentication should be explicitly injected as well.




Is it ok to leave it like this or I should create my own userManager which will be using uow and repositories?




Entity Framework is already built following the UOW/Repository pattern and Identity Framework is built on top of it.



UserManager and by extension Identity Framework is more of an implementation concern/detail that you can encapsulate behind your own abstraction in whatever structure/pattern you want.



Instead of focusing on that pattern consider just creating a service to perform the desired functionality and inject that into your dependent classes.






share|improve this answer























  • Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
    – Marek Czaplicki
    Mar 19 at 22:05










  • @MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
    – Nkosi
    Mar 20 at 12:55











  • do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
    – Marek Czaplicki
    Mar 20 at 13:13










  • Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
    – Nkosi
    Mar 20 at 13:16










  • In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
    – Marek Czaplicki
    Mar 20 at 13:21










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f189934%2fasp-net-identity-2-0-usermanager-alongside-with-unitofwork-and-service-locator-a%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










First, avoid .Result within async methods



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
//...

var userList = this.unitOfWork.UserRepository.GetAll().Result;

//...



as those blocking calls can lead to deadlocks. Make the function async all the way through



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
if (this.ModelState.IsValid)
var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = await this.unitOfWork.UserRepository.GetAll();
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



Next, it appears that DI and service locator is being mixed.



var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;


could be seen as a service locator anti-pattern within the action being called.



Assuming the unitOfWork is being injected into the controller then user manager and authentication should be explicitly injected as well.




Is it ok to leave it like this or I should create my own userManager which will be using uow and repositories?




Entity Framework is already built following the UOW/Repository pattern and Identity Framework is built on top of it.



UserManager and by extension Identity Framework is more of an implementation concern/detail that you can encapsulate behind your own abstraction in whatever structure/pattern you want.



Instead of focusing on that pattern consider just creating a service to perform the desired functionality and inject that into your dependent classes.






share|improve this answer























  • Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
    – Marek Czaplicki
    Mar 19 at 22:05










  • @MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
    – Nkosi
    Mar 20 at 12:55











  • do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
    – Marek Czaplicki
    Mar 20 at 13:13










  • Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
    – Nkosi
    Mar 20 at 13:16










  • In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
    – Marek Czaplicki
    Mar 20 at 13:21














up vote
2
down vote



accepted










First, avoid .Result within async methods



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
//...

var userList = this.unitOfWork.UserRepository.GetAll().Result;

//...



as those blocking calls can lead to deadlocks. Make the function async all the way through



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
if (this.ModelState.IsValid)
var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = await this.unitOfWork.UserRepository.GetAll();
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



Next, it appears that DI and service locator is being mixed.



var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;


could be seen as a service locator anti-pattern within the action being called.



Assuming the unitOfWork is being injected into the controller then user manager and authentication should be explicitly injected as well.




Is it ok to leave it like this or I should create my own userManager which will be using uow and repositories?




Entity Framework is already built following the UOW/Repository pattern and Identity Framework is built on top of it.



UserManager and by extension Identity Framework is more of an implementation concern/detail that you can encapsulate behind your own abstraction in whatever structure/pattern you want.



Instead of focusing on that pattern consider just creating a service to perform the desired functionality and inject that into your dependent classes.






share|improve this answer























  • Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
    – Marek Czaplicki
    Mar 19 at 22:05










  • @MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
    – Nkosi
    Mar 20 at 12:55











  • do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
    – Marek Czaplicki
    Mar 20 at 13:13










  • Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
    – Nkosi
    Mar 20 at 13:16










  • In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
    – Marek Czaplicki
    Mar 20 at 13:21












up vote
2
down vote



accepted







up vote
2
down vote



accepted






First, avoid .Result within async methods



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
//...

var userList = this.unitOfWork.UserRepository.GetAll().Result;

//...



as those blocking calls can lead to deadlocks. Make the function async all the way through



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
if (this.ModelState.IsValid)
var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = await this.unitOfWork.UserRepository.GetAll();
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



Next, it appears that DI and service locator is being mixed.



var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;


could be seen as a service locator anti-pattern within the action being called.



Assuming the unitOfWork is being injected into the controller then user manager and authentication should be explicitly injected as well.




Is it ok to leave it like this or I should create my own userManager which will be using uow and repositories?




Entity Framework is already built following the UOW/Repository pattern and Identity Framework is built on top of it.



UserManager and by extension Identity Framework is more of an implementation concern/detail that you can encapsulate behind your own abstraction in whatever structure/pattern you want.



Instead of focusing on that pattern consider just creating a service to perform the desired functionality and inject that into your dependent classes.






share|improve this answer















First, avoid .Result within async methods



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
//...

var userList = this.unitOfWork.UserRepository.GetAll().Result;

//...



as those blocking calls can lead to deadlocks. Make the function async all the way through



[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(User model)
if (this.ModelState.IsValid)
var user = await this.unitOfWork.UserRepository.Get(model.Id);
user.EditUser(model);
await this.unitOfWork.Complete();
return this.RedirectToAction("Index");

var userList = await this.unitOfWork.UserRepository.GetAll();
this.ViewBag.SuperiorId = new SelectList(userList, "Id", "FirstName", model.SuperiorId);
return this.View(model);



Next, it appears that DI and service locator is being mixed.



var userManager = this.HttpContext.GetOwinContext().GetUserManager<LeaveUserManager>();
var authManager = this.HttpContext.GetOwinContext().Authentication;


could be seen as a service locator anti-pattern within the action being called.



Assuming the unitOfWork is being injected into the controller then user manager and authentication should be explicitly injected as well.




Is it ok to leave it like this or I should create my own userManager which will be using uow and repositories?




Entity Framework is already built following the UOW/Repository pattern and Identity Framework is built on top of it.



UserManager and by extension Identity Framework is more of an implementation concern/detail that you can encapsulate behind your own abstraction in whatever structure/pattern you want.



Instead of focusing on that pattern consider just creating a service to perform the desired functionality and inject that into your dependent classes.







share|improve this answer















share|improve this answer



share|improve this answer








edited Mar 19 at 17:42


























answered Mar 19 at 17:34









Nkosi

1,870619




1,870619











  • Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
    – Marek Czaplicki
    Mar 19 at 22:05










  • @MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
    – Nkosi
    Mar 20 at 12:55











  • do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
    – Marek Czaplicki
    Mar 20 at 13:13










  • Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
    – Nkosi
    Mar 20 at 13:16










  • In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
    – Marek Czaplicki
    Mar 20 at 13:21
















  • Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
    – Marek Czaplicki
    Mar 19 at 22:05










  • @MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
    – Nkosi
    Mar 20 at 12:55











  • do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
    – Marek Czaplicki
    Mar 20 at 13:13










  • Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
    – Nkosi
    Mar 20 at 13:16










  • In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
    – Marek Czaplicki
    Mar 20 at 13:21















Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
– Marek Czaplicki
Mar 19 at 22:05




Thanks for pointing out using .Result in async methods. I have fixed this in all project :). If I understood correctly - It would be good for me to create a service that would take some of the functionality (that I need) from userManager and would use my UoW? I know that EF is based on UoW and Repos, but in this case I have my custom UoW and user Manager is not using my custom uow.
– Marek Czaplicki
Mar 19 at 22:05












@MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
– Nkosi
Mar 20 at 12:55





@MarekCzaplicki That works perfectly, and saves you from having to build your own service. My only issue is that classes should depend on abstractions and not concretions. While injecting the class in you scenario works, it is not a very good design.
– Nkosi
Mar 20 at 12:55













do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
– Marek Czaplicki
Mar 20 at 13:13




do you mean like I should use UserManager instead of LeaveUserManager, or you mean something else?
– Marek Czaplicki
Mar 20 at 13:13












Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
– Nkosi
Mar 20 at 13:16




Not necessarily. An interface would be as abstract as you can get, but like I said before, what you have can work.
– Nkosi
Mar 20 at 13:16












In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
– Marek Czaplicki
Mar 20 at 13:21




In case of UserManager there is no interface, but I could still use it, because it is still more abstract than LeaveUserManager. I am pretty new to Dependency Injection in practice, so I just want to understand how things should work in live project
– Marek Czaplicki
Mar 20 at 13:21












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f189934%2fasp-net-identity-2-0-usermanager-alongside-with-unitofwork-and-service-locator-a%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation