Спелый рефакторинг - внедрение зависимостей .NET - PullRequest
3 голосов
/ 09 июня 2011

Как и большинство людей, я начал понимать некоторые входы и выходы Entity Framework. Одной из таких вещей является время жизни контекста. Я использую репозитории и решил, что контекст будет жить для длины запроса. Таким образом, контекст должен вводиться с веб-уровня везде, где используется этот репозиторий.

Я написал некоторый код, который, я уверен, может быть реорганизован (на самом деле, определенно!). Итак, основываясь на концепции выше, как бы вы оптимизировали следующий помощник хранилища?

public class RepositoryHelper
{

    public static CountryRepository GetCountryRepository() {
        return new CountryRepository(HttpContext.Current.GetObjectContext());
    }

    public static CurrencyRepository GetCurrencyRepository()
    {
        return new CurrencyRepository(HttpContext.Current.GetObjectContext());
    }

    public static SettingRepository GetSettingRepository()
    {
        return new SettingRepository(HttpContext.Current.GetObjectContext());
    }

}

Репозиторий довольно прост и будет выглядеть как

public class CountryRepository
{

    private Context _context = null;
    public CountryRepository(Context context)
    {
        _context = context;
    }

    public Country GetById(int id) 
    {
        // Would return a country
    }

    public IEnumerable<Country> All()
    {
        // Would return a list of countries
    }

}

Ответы [ 4 ]

2 голосов
/ 09 июня 2011

Проблема здесь в том, что то, что вы создали, не является хранилищем в смысле шаблона хранилища.Целью шаблона репозитория является абстрагирование реализации уровня доступа к данным от проблемной области.Это делается через репозиторий, который ведет себя как коллекция объектов домена в памяти, с которой вы можете выполнять обычные функции CRUD и часто несколько более специфических операций, например, GetByID (id).

Затем репозиторий скрываетфактический уровень персистентности из действующего приложения, позволяющий вам изменять этот уровень без влияния на приложение, то есть вы можете начать с сохранения данных в плоском файле, а затем перейти к СУБД.

Обычно вы создаете интерфейс дляОпишите методы, которые необходимо реализовать в вашем репозитории, и фактически передайте экземпляр репозитория, используя этот интерфейс в качестве типа.Это абстракция, интерфейс является общим для всех возможных конкретных реализаций вашего репозитория, но ваше приложение не обращает внимания (в некоторой степени), которое фактически используется.

Я бы предложил сделать шаг назад, посмотрите еще разна шаблон репозитория и посмотреть, если вам это нужно.Убедитесь, что вы реализуете его не только ради этого, и что вы не увеличиваете сложность своего приложения без необходимости.Выбрав подход к доступу к данным, вы сможете узнать, как лучше всего использовать имеющиеся у вас контексты EF.

0 голосов
/ 09 июня 2011

Для DI вы можете использовать Ninject и использовать метод InRequestScope при связывании объектов.

0 голосов
/ 09 июня 2011

Прочтите мой ответ здесь о том, как сделать универсальный менеджер сеансов.

Затем создайте менеджер сеанса EntityFramework (в котором хранится объектный текст).

Какой-то недоделанный псевдокод:

public static class EntityFrameworkSession
{
    [ThreadStatic] private static ObjectContext _current;

    public static AssignToSessionFactory()
    {
         SessionFactory.Created += OnCreateObjectContext;
         SessionFactory.Disposed += OnDisposeContext;
    }

    public static void OnDisposeContext(object source, SessionEventArgs e)
    {
         if (e.Saved)
           _myContext.SaveChanges();
    }
}

А в ваших репозиториях используйте:

EntityFrameworkSession.Current

для доступа к контексту.

0 голосов
/ 09 июня 2011

Думаю, вам было бы полезно использовать класс провайдера репозитория и фабрики репозитория, как в ответе на C # / EF и шаблон репозитория: куда поместить ObjectContext в решение с несколькими репозиториями? .

...