Add MVC 5 UserManager<ApplicationUser> to register with Unity Framework? - unity-container

Hi i am using MVC 5 + EF6 and want to register MVC 5 Application User and other specific types using Unity 3 but i am getting errors.
My Context Class:
public class ProjectContext : IdentityDbContext<ApplicationUser>
{
public ProjectContext()
: base("ProjectContext")
{
}
public DbSet<User> Users { get; set; }
public DbSet<UserProfile> UserProfile { get; set; }
public virtual void Commit()
{
base.SaveChanges();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Controller Class:
public class AccountController : Controller
{
private UserManager<ApplicationUser> UserManager;
private IUserService userService;
private IUserProfileService userProfileService;
public AccountController(IUserService userService, IUserProfileService userProfileService, UserManager<ApplicationUser> userManager)
{
this.userService = userService;
this.userProfileService = userProfileService;
this.UserManager = userManager;
}
}
I have used the following registration in combinations but i am getting errors
--> ProjectArchitecture.Web.Controllers.AccountController does not have a constructor that takes the parameters (). When all 1-4 are commented above
--> The type DbConnection does not have an accessible constructor.
Unity Registration Code:
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
container.RegisterType<IRoleStore<IdentityRole>, RoleStore<IdentityRole>>();
container.RegisterType<AccountController>(new InjectionConstructor());
container.RegisterInstance(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ProjectEntities())));

Related

net core 2.2 local customized user account System.InvalidOperationException

I created project in net core 2.2 with local user account and added all identity files using scaffolding. I created in my model folder two files ApplicationUser.cs and ApplicationRole.cs. Then I modified startup.cs and applicationdbcontext to use new attributes for user and role. Now I have to change all relations from IdentityUser to ApplicationUser in all classes in Areas/Identity. Am I missing something or this is expected behavior?
I get the error before changing relation from IdentityUser to ApplicationUser.
Unable to resolve service for type 'Microsoft.AspNetCore.Identity.SignInManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'Areas.Identity.Pages.Account.LogoutModel'.
private readonly SignInManager _signInManager;
to
private readonly SignInManager<ApplicationUser> _signInManager;
public class ApplicationRole : IdentityRole
{
public string Description { get; set; }
public string DisplayName { get; set; }
}
public class ApplicationUser : IdentityUser
{
public string Name { get; set; }
public string Surname { get; set; }
public string Fullname { get; set; }
}
startup.cs
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
ApplicationDbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
I want to be sure that I didn't miss something or made a mistake.
Based on the code you have shown, the main problem that stands out to me is that you never assign anything to _signInManager.
class Foo // your class
{
private readonly SignInManager<ApplicationUser> _signInManager;
public Foo() // your constructor
{
_signInManager = ; //<-- this
}
}
Which at this point, shows that it is defined as null.

Unit of Work - All Repositories need to be properties?

I am trying to use Repository/UoW Patternin a .net core project . I have looked at many implementations across web . In all the implementations repositories are created as properties in IUnitOfWork.
In Future if we have 50 Repositories we need to have 50 properties in the Unit of Work . Could anyone suggest a better approach for implementing Repository/UoW.
Please Find below the code snippets of approach i have implemented currently.
IUnitOfWork.cs
IStudentRepository Student { get; set; }
IClassRepository Class { get; set; }
void Complete();
UnitOfWOrk.cs
public class unitofwork {
private readonly CollegeContext _context;
IStudentRepository Student { get; set; }
IClassRepository Class { get; set; }
public UnitOfWork(CollegeContext CollegeContext)
{
this._context = CollegeContext;
Student = new StudentRepository(_context);
Class = new ClassRepository(_context);
}
public void Complete()
{
return _context.SaveChanges();
}
}
Student and Class Repositories Inherit From a generic Repository class and IStudentRepository and IClassRepository respectively.
StudentRepository.cs
public class StudentRepository : Repository<Student> , IStudentRepository
{
private readonly CollegeContext context;
private DbSet<Student> entities;
public StudentRepository(CollegeContext context) : base(context)
{
this.context = context;
entities = context.Set<Student>();
}
}
Property-per-Repository is not convenient in some cases as you said. I generally use some sort of factory method in UoW class as below:
public class unitofwork
{
private readonly CollegeContext _context;
IStudentRepository Student { get; set; }
IClassRepository Class { get; set; }
public UnitOfWork(CollegeContext CollegeContext)
{
this._context = CollegeContext;
}
public T CreateRepository<T>() where T : IRepository
{
IRepository repository = null;
if(typeof(T) == typeof(IStudentRepository))
repository = new StudentRepository(_context);
......
......
else
throw new XyzException("Repository type is not handled.");
return (T)repository;
}
public void Complete()
{
return _context.SaveChanges();
}
}
public interface IRepository
{
Guid RepositoryId { get; }
}
My IRepository just hold a simple property. You may extend this interface as per your needs.

Asp.Net Core: Add data to IdentityDbContext or use DbContext

I work with Asp.Net Core WebApi project.
Can I add my tables to IdentityDbContext, like this:
public class ApplicationDbContext : IdentityDbContext<User>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{ }
public DbSet<ProgrammerRole> ProgrammerRoles { get; set; }
public DbSet<Project> Projects { get; set; }
public DbSet<SubProject> SubProjects { get; set; }
public DbSet<Report> Reports { get; set; }
}
Or do I need to create a second DbContext. And if i create a second DbContext
how can I communicate wiht User in IdentityDbContext.
And my second question:
If i add data in IdentityDbContext, like above, How do I get the data from my tables in ApplicationDbContext?
Because i need to pass DbContextOptions object every time I create a new instance оf ApplicationDbContext. I do this in Startup.cs:
// ===== Add DbContext ========
var connectionString = Configuration.GetConnectionString("DbConnection");
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
I saw in older version of Asp.Net Core, that i can pass Connection String in IdentityDbContext constructor, but now only DbContextOptions.
And i can't do, for example this:
[AllowAnonymous]
[HttpGet]
public IEnumerable<Project> GetRoles()
{
using (var db = new ApplicationDbContext())
{
return db.Projects;
}
}
Can I add my tables to IdentityDbContext, like this:
Yes, it is how you create custom tables. You do not need to create another DbContext. E.g.
public class Project
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Project> Projects { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Project>(entity =>
{
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(50);
});
base.OnModelCreating(builder);
}
}
Note: you might need to run dotnet ef migrations add Initial and dotnet ef database update for database migration.
using (var db = new ApplicationDbContext()) {...}
You should not create or manage ApplicationDbContext inside controller. If you do so, they become tightly coupled, and you cannot implement unit tests.
Instead, you let dependency inversion (DI) container manage it for you. E.g.
public class UserController : Controller
{
private readonly ApplicationDbContext _context;
public UserController(ApplicationDbContext context)
{
_context = context;
}
[AllowAnonymous]
[HttpGet]
public IEnumerable<Project> GetRoles()
{
return _context.Projects;
}
}
I solve my problem, i just replaced code in my ApplicationDbContext, and get connection string from method:
public class ApplicationDbContext : IdentityDbContext<User>
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(GetConnectionString());
}
private static string GetConnectionString()
{
const string databaseName = "EmployeeReportsDb";
const string databasePass = "SuperPuper_Random_DB-key!";
return $"Server=localhost;" +
$"database={databaseName};" +
$"Trusted_Connection = True;" +
$"MultipleActiveResultSets = True;" +
$"pwd={databasePass};" +
$"pooling=true;";
}
public DbSet<ProgrammerRole> ProgrammerRoles { get; set; }
public DbSet<Project> Projects { get; set; }
public DbSet<SubProject> SubProjects { get; set; }
public DbSet<Report> Reports { get; set; }
}
here is the resource: https://medium.com/#ozgurgul/asp-net-core-2-0-webapi-jwt-authentication-with-identity-mysql-3698eeba6ff8

Cannot convert from Repository to IRepository UOW Repository pattern

I am trying a MVC project with repository pattern and unit of work.
The following is from my InitOfWork
public interface IUnitOfWork
{
IRepository<User> UserRepository { get; }
void Save();
}
and this is from UnitOfWork
public class UnitOfWork:IUnitOfWork, IDisposable
{
private JNContext context = new JNContext();
private bool disposed = false;
private IRepository<User> userRepository;
public IRepository<User> UserRepository
{
get
{
if (this.userRepository == null)
{
this.userRepository = new Repository<User>(this.context);
}
return this.userRepository;
}
}
public void Save()
{
this.context.SaveChanges();
}}
The following line in UnitOfWork generates the error 'Cannot implicitly convert from Repository to IRepository
this.userRepository = new Repository<User>(this.context);
What am I missing. I cannot find an answer and I am stuck the entire day.
Try something like this
public interface IRepository<T> where T : class
{
IQueryable<T> Entities { get; }
void Remove(T entity);
void Add(T entity);
}
public class GenericRepository<T> : IRepository<T> where T : class
{
private readonly MyDbContext _dbContext;
private IDbSet<T> _dbSet => _dbContext.Set<T>();
public IQueryable<T> Entities => _dbSet;
public GenericRepository(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public void Remove(T entity)
{
_dbSet.Remove(entity);
}
public void Add(T entity)
{
_dbSet.Add(entity);
}
}
Found a good article about it here: https://medium.com/#utterbbq/c-unitofwork-and-repository-pattern-305cd8ecfa7a

SignalR multiple requests

I'm new to the forum and in the "world" of programming. I bumped into a problem while creating a game with SignalR Web technology and it is expressed in terms of access to the database (using EF) with multiple requests from UI-a. What is the best solution using the repository pattern? The decision to me at this stage is added Lock {} structure in each method, which accesses the database. How can I avoid blocking requests to a server?
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(object id);
void Add(T item);
void Update(T item);
void Delete(T item);
void Delete(object id);
}
public class DBRepository<T> : IRepository<T> where T : class
{
private DbContext DbContext;
private DbSet<T> Entities
{
get
{
return this.DbContext.Set<T>();
}
}
public DBRepository(DbContext context)
{
this.DbContext = context;
}
public IQueryable<T> GetAll()
{
return Entities.AsQueryable();
}
.....
public class TicTacToeContext : DbContext
{
public DbSet<Game> Games { get; set; }
public DbSet<Guess> Guesses { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<MessageState> MessageStates { get; set; }
public DbSet<MessageType> MessageTypes { get; set; }
public DbSet<User> Users { get; set; }
public TicTacToeContext()
: base("TicTacToeDb")
{
}
public interface IGameService
{
void CreateGame(CreateGameModel gameModel);
void JoinGame(JoinGameModel gameModel);
...
public abstract class BaseService
{
public IRepository<User> UserRepository;
public IRepository<Game> GameRepository;
...
public class GameService : BaseService, IGameService
{
public GameService(IRepository<Game> gameRepositort, IRepository<User> userRepository, ISessionService sessionService)
{
this.UserRepository = userRepository;
this.GameRepository = gameRepositort;
}
public void CreateGame(CreateGameModel gameModel)
{
....
}
public class TicTacToeHub : Hub
{
IUserService UserServise;
IGameService GameServise;
private static object _syncRoot = new object();
public TicTacToeHub(IUserService userService, IGameService gameService)
{
this.UserServise = userService;
this.GameServise = gameService;
}
.....
public void ReturnOpenGamesToClient(string sessionKey)
{
IEnumerable<GameModel> openGames;
lock (_syncRoot)
{
openGames = GameServise.GetOpenGames(sessionKey).ToList();
}
Clients.Caller.updateOpenGamesList(openGames);
}
Why locks? You use a DB and only update one entity (No transaction scope needed).
Locks needs to be used for Inmemory types like IList or IDictionary otherwise it will crash when one request reads and another one writes. But SQL takes care of this for you

Resources