Marthijn
Marthijn

Reputation: 3392

Entity Framework extensible framework

In many projects I have to make a table containing users and implementing standard user-based functions such as authentication, saving, etc. So I decided to make a class library containing these functionalities, for example:

public class User
{
  public int? Id {get;set;}
  public string UserName {get;set;}
  public string Password {get;set;}
}

public class MyDbContext : DbContext
{
  public DbSet<User> {get;set;}
}

public class UserService
{
  public MyDbContext Context {get;set;} // will be initialized in constructor

  public User GetByUserName(string username)
  {
    return (from s in Context.Users where s.UserName.Equals(username) select s).SingleOrDefault();
  }

  // etc...
}

Now when I start a new Mvc project I add this library and extends the DbContext with custom models. The problem is I don't know how to extend the User table with some additional fields, for example:

public class MyUser : User
{
   public bool IsApproved {get;set;}
}

public class CustomDbContext : MyDbContext
{
  public DbSet<SomeOtherModel> {get;set;}

  // problem: override DbSet in MyDbContext with class MyUser?
  //public DbSet<MyUser> {get;set;}
}

In this case I also need to override the DbSet<User> of the MyDbContext. If I remove the DbSet<User> in the library my UserService class won't work anymore. Any ideas how to make an extensible framework?

Upvotes: 2

Views: 566

Answers (3)

Davin Tryon
Davin Tryon

Reputation: 67316

You could always use composition and have MyUser contain a User property. Then, you would have a brand-new DbContext that would have a DbSet.

This would create two tables in the database, but is probably the easiest. (disclaimer: haven't tried this and you may encounter cross-assembly issues)

Upvotes: 0

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93444

Don't inherit from User, instead make User a partial class and extend User that way. That only works if your library is just a set of source files, and not compiled into an assembly.

EDIT:

Another option is to simply not define the dbcontext in your framework, and define it using your library classes in your application project. You could then call an initialization function in your framework to do the mappings you need and call it from OnModelCreating.

Upvotes: 2

Paul Tyng
Paul Tyng

Reputation: 7584

You could use generics (I haven't tested this, just a thought):

public abstract class UserDbContext<TUser> : DbContext where TUser : User
{
  public DbSet<TUser> Users {get;set;}
}

And then inherit:

public class CustomDbContext : MyDbContext<MyUser>

And the same generic in the UserService:

public abstract class UserService<TUser> where TUser : User
{
  public UserDbContext<TUser> Context {get;set;} // will be initialized in constructor

  public TUser GetByUserName(string username)
  {
    return (from s in Context.Users where s.UserName.Equals(username) select s).SingleOrDefault();
  }

  // etc...
}

Upvotes: 2

Related Questions