Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging ASP.Net Identity DbContext with my DbContext

I'm using the default ASP.Net MVC template in Visual Studio. I'm using the ASP.Net Identity code that was created for me in the template. I'd like for the DBContext I use to be aware of the relationship between the ApplicationUser entity (AspNetUser table) and the rest of my entities. For example, I want to be able to have an ApplicationUser.Messages property that exhibits the relationship between the ApplicationUser and Message entities. I have my DbContext for all non-Identity entities in a Data Access Layer project. And the template ApplicationDbContext is in the UI Layer. In order to keep the relationships between the Identity entities and my custom entities, I need to merge into one DbContext, right? How do I do this?

Here is some sample code of what I have:

The IdentityUser and DbContext created for me in the UI Layer project from the MVC template with my custom Messages property:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    public ICollection<Message> Messages { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

The Message class I have in my Domain/Business Logic Layer:

public class Message
{

    public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    [Required]
    public string Body { get; set; }

    [Required]
    public DateTime Created { get; set; }
}

The DBContext I have in my Data Access Layer project:

public class PSNContext : DbContext, IPSNContext
{
    public PSNContext()
        :base ("DefaultConnection")
    {
    }

    public DbSet<Message> Messages { get; set; }
}

It doesn't feel right to bring UI-specific code like this from the ApplicationUser in the UI Layer into my Business Logic Layer:

var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

Is there a better way to do this?

like image 411
drewob Avatar asked Apr 02 '16 00:04

drewob


1 Answers

This has already been answered here

With regards to moving ApplicationUser into a logic layer, I personally think it's fine. The logic there does not make use of Web specific namespaces. The ones in use are Microsoft.AspNet.Identity and System.Security.Claims related. In this instance ApplicationUser is the entity, your web layer should be using ClaimsPrincipal for authentication and authorization.

If you'd like an example, I've previously done this merge before. Although it's not in an ideal state, it should serve as an example for what you are trying to achieve.

like image 99
Henry Lu Avatar answered Oct 13 '22 00:10

Henry Lu