How to use Entity Framework context with dependenc

2019-04-12 14:53发布

问题:

I'm trying to setup a base Repository class that can use the Entity Framework edmx model context. The problem I'm having is that I need to find an interface that the EF EDMX object context implements so I can pass to the constructor via dependency injections. I've got around this before by using a DataFactory that creates it and stores it in the HttpContext but that kills the ability to unit test. Any help would be appreciated. Thanks!

public abstract class BaseRepository<T> where T : EntityObject
{
        private MyDataModelContext _dataContext;
        private ObjectSet<T> dbset;

        protected BaseRepository(IObjectContext dataContext)
        {
            _dataContext = dataContext;
            dbset = _dataContext.CreateObjectSet<T>();
        }

    .....

回答1:

I've always created a DataContextFactory that passes my own interface to the Context, and passed that to my repositories like so:

The context interface:

public IMyDataContext {
    // One per table in the database
    IDbSet<Class1> Class1s { get;set; }
    // etc

    // The standard methods from EF you'll use
    void Add( object Entity );
    void Attach( object Entity );
    void Delete( object Entity );
    void SaveChanges();
}

The context factory:

public class MyDataContextFactory : IMyDataContextFactory {
    public IMyDataContext GetContext() {
        // TODO: Use the service locator pattern to avoid the direct instanciation
        return new MyDataContext();
    }
}

The context factory interface:

public interface IMyDataContextFactory {
    IMyDataContext GetContext();
}

The repository:

public class MyClass1Repository {
    private readonly IMyDataContextFactory factory;
    public MyClass1Repository( IMyDataContextFactory Factory ) {
        // TODO: check for null
        this.factory = Factory;
    }
    public List<MyClass1> GetAll() {
        using ( IMyDataContext db = this.factory.GetContext() ) {
            return db.Class1s.ToList();
        }
    }
    // TODO: Other methods that get stuff
}

Then when I want to test the repository, I pass in a fake IMyDataContextFactory that returns a fake IMyDataContext from GetContext().

In time I notice duplication in repositories, and can push certain methods into the base repository: GetAll(), Save(), GetById() sometimes if I have consistent primary keys, etc.