Reputation: 3392
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
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
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
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