Search code examples
c#entity-frameworkasp.net-identity

How to eliminate the Microsoft.AspNet.Identity.EntityFramework dependency when using an inherited Context?


I'm creating a base C# library for ASP.NET MVC 5 projects for the company I work for, so when we have to share source code, we would include references to Enterprise.Classes library and the original dependencies are not required since this class would integrate all functionality.

For the DbContext, we have created a custom context that inherits from IdentityDbContext, but whenever it is inherited to create new contexts, the Microsoft.AspNet.Identity.EntityFramework Nuget package is required to be installed to work.

So far this is the code for the custom DbContext:

[DbConfigurationType(typeof(EnterpriseDbConfiguration))]
public class EnterpriseDbContext : IdentityDbContext<EnterpriseUser, EnterpriseRole, long, EnterpriseUserLogin,
    EnterpriseUserRole, EnterpriseUserClaim>
{
    public EnterpriseDbContext(string contextName = "DefaultEnterpriseConnection") : base(contextName)
    {
        /* Entities, Configurations and stuff */
    }
}

And here is an example of the EnterpriseUser class (which would be the IdentityUser class):

public class EnterpriseUser : IdentityUser<long, EnterpriseUserLogin, EnterpriseUserRole, EnterpriseUserClaim>
{
    public EnterpriseUser()
    {
        RegistrationDate = DateTime.Now;
        Enabled = true;
    }

    /* Additional Properties */
}

Here is an example of an inheriting context, when EnterpriseDbContext is marked for inheritance it requires the Microsoft.AspNet.Identity.EntityFramework Nuget package to be installed:

public class InheritedEnterpriseContext : EnterpriseInfrastructure.Data.EnterpriseDbContext
{

}

How can I build the EnterpriseDbContext so when it is inherited it won't require the Nuget package to be installed?

Captura Visual Studio


Solution

  • The issue will be that by exposing a class that directly inherits, consumers of that class will need to know about all public shared members, requiring a dependency on the AspNet.Identity.EntityFramework library whether you intend to use them or not.

    Edit: Corrections around IdentityDbContext and it's purpose...

    IdentityDbContext is used for ASP.Net's authentication/authorization so your options are to either extend IdentityDbContext in which case you will need to reference ASPNet.Identity.EntityFramework anywhere your DbContext is referenced, or use separate contexts for your Identity and Application information.

    You can define your EnterpriseUser/Role classes and construct an IdentityDbContext Instance to provide to your UserStore etc. for Auth. Then define your EnterpriseDbContext to extend DbContext. It too can define DbSets for EnterpriseUser/Role as you see fit. This DbContext can be shared/referenced by other code. Any MVC project that you want to use the IdentityDbContext will obviously need ASPNet.Identity.EntityFramework. Other libraries would use your EnterpriseDbContext /w just the normal EF reference.

    public class EnterpriseDbContext : DbContext
    {
        public DbSet<EnterpriseUser> EnterpriseUsers { get; set; }
        // .. Your data entities.
    }
    

    If EnterpriseUser extends IdentityUser you will likely still have a dependency to .Identity.EntityFramework. In this case you should define an alternative "User" entity for your EnterpriseDbContext that proxies for EnterpriseUser and use that in it's place for the application DbContext.

    I.e.

    // Can't use this in our EnterpriseDbContext because IdentityUser will require ref. to .Identity.EntityFramework
    public class EnterpriseUser : IdentityUser<Guid>
    {
       // Stuff.
    }
    
    // Use this instead in our EnterpriseDbContext to map to the same table
    [Table("EnterpriseUsers")]
    public class User
    {
       public Guid Id { get; set; }
       public string UserName { get; set; }
       // Stuff...
    }