Это действительно зависит от того, как вы хотите выставить свой репозиторий / хранилище данных.
Не уверен, что вы подразумеваете под "контекст будет закрыт, поэтому я не могу заниматься бизнес-логикой". Сделайте свою бизнес-логику внутри оператора using. Или, если ваша бизнес-логика находится в другом классе, тогда давайте продолжим. :)
Некоторые люди возвращают конкретные коллекции из своего репозитория, и в этом случае вы можете заключить контекст в оператор using:
public class ArticleRepository
{
public List<Article> GetArticles()
{
List<Article> articles = null;
using (var db = new ArticleNetEntities())
{
articles = db.Articles.Where(something).Take(some).ToList();
}
}
}
Преимущество этого заключается в удовлетворении хорошей практики со связями - открывайте как можно позже и закрывайте как можно раньше.
Вы можете инкапсулировать всю свою бизнес-логику внутри оператора using.
Недостатки - ваш репозиторий узнает о бизнес-логике, которая лично мне не нравится, и вы получаете разные методы для каждого конкретного сценария.
Второй параметр - создает новый контекст как часть репозитория и делает его реализующим IDisposable.
public class ArticleRepository : IDisposable
{
ArticleNetEntities db;
public ArticleRepository()
{
db = new ArticleNetEntities();
}
public List<Article> GetArticles()
{
List<Article> articles = null;
db.Articles.Where(something).Take(some).ToList();
}
public void Dispose()
{
db.Dispose();
}
}
А потом:
using (var repository = new ArticleRepository())
{
var articles = repository.GetArticles();
}
Или третий вариант (мой любимый), используйте внедрение зависимостей . Отсоедините всю контекстную работу от вашего репозитория и позвольте контейнеру DI обработать удаление ресурсов:
public class ArticleRepository
{
private IObjectContext _ctx;
public ArticleRepository(IObjectContext ctx)
{
_ctx = ctx;
}
public IQueryable<Article> Find()
{
return _ctx.Articles;
}
}
Выбранный вами DI-контейнер внедрит конкретный ObjectContext в экземпляр Repository с настроенным временем жизни (Singleton, HttpContext, ThreadLocal и т. Д.) И утилизирует его на основе этой конфигурации.
У меня настроено так, что каждый HTTP-запрос получает новый контекст. Когда запрос будет выполнен, мой контейнер DI автоматически избавится от контекста.
Здесь я также использую шаблон «Единица работы», чтобы несколько репозиториев могли работать с одним контекстом объекта.
Возможно, вы также заметили, что я предпочитаю возвращать IQueryable из моего репозитория (в отличие от конкретного списка). Гораздо более мощным (но рискованным, если вы не понимаете последствий). Мой сервисный уровень выполняет бизнес-логику для IQueryable и затем возвращает конкретную коллекцию в пользовательский интерфейс.
Это мой самый мощный вариант, так как он позволяет использовать простой, как хек, репозиторий, единица работы управляет контекстом, сервисный уровень управляет бизнес-логикой, а контейнер DI управляет временем жизни / удалением ресурсов / объектов. .
Дайте мне знать, если вы хотите получить больше информации об этом - поскольку в этом есть много, даже больше, чем этот удивительно длинный ответ. :)