问题
I am trying to make an interface out of ApplicationDbContext which extends IdentityDbContext.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>,
IApplicationDbContext
{
public ApplicationDbContext()
: base("AppContext")
{
}
// Should I add below line? without any unwanted behavior?
// public DbSet<ApplicationUser> User { get; set;}
public DbSet<Book> Books { get; set; }
}
My interface will be
public interface IApplicationDbContext : IDisposable
{
// Should I add below line?
// DbSet<ApplicationUser> User { get;}
DbSet<Book> Books { get; }
int SaveChanges();
}
On problem with this approach is that I loose access to 'Users' that came from IdentityDbContext.Users
private ApplicationDbContext ctx = new ApplicationDbContext();
ctx.Users.somthing() works
but with below, compiler complains
private IApplicationDbContext ctx = new ApplicationDbCOntext();
ctx.Users.something..
IApplicationDbContext does not contain a definition for 'Users' and no extensions method 'Users'...
I think I am missing a crucial concept here.
would you help me out?
回答1:
If you delcare ctx
as an instance of IApplicationDbContext
you're delcaring your intent that you only wish to know about those things in the IApplicationDbContext
interface, regardless of what the concrete implementation of the interface happens to be.
If you want access to both IdentityDbContext<ApplicationUser>
members and IApplicationDbContext
members, you need to delcare a type which is both of those things, e.g. your ApplicationDbContext
class.
Alternatively, and preferably, rather than extend IdentityDbContext<ApplicationUser>
in your concrete implementation of ApplicationDbContext
, you could instead follow the principle of prefering composition over inheritance, and allow ApplicationDbContext
to own an instance of IdentityDbContext<ApplicationUser>
, e.g.
public class ApplicationDbContext : IApplicationDbContext
{
private readonly IdentityDbContext<ApplicationUser> _dbContext;
public IDbSet<ApplicationUser> Users { get { return _dbContext.Users; } }
public ApplicationDbContext(IdentityDbContext<ApplicationUser> dbContext)
{
_dbContext = dbContext;
}
public DbSet<Book> Books { get; set; }
}
and, if you needed to, alter your interface definition to also provide the Users
property. This allows you to still access the information you need, while hiding the information you don't. See
http://en.wikipedia.org/wiki/Composition_over_inheritance and http://en.wikipedia.org/wiki/Information_hiding for more information.
来源:https://stackoverflow.com/questions/26172368/how-to-make-an-interface-class-out-of-applicationdbcontext