Настройка структуры приложения EF - PullRequest
5 голосов
/ 05 августа 2011

Я работаю над прототипом приложения EF, используя POCO.В основном, как введение в фреймворк, я задаюсь вопросом о хорошем способе настройки приложения в хорошую структуру.Позже я планирую включить в него WCF.

Я сделал следующее:

1) Я создал файл edmx, но со свойством генерации кода установлено значение Нети сгенерировал мою схему базы данных,

2) Я создал POCO, которые все выглядят так:

public class Person
{
    public Person()
    { 
    }

    public Person(string firstName, string lastName)
    {        

        FirstName = firstName;
        LastName = lastName;
    }

    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

3) Я создал Context

public class PocoContext : ObjectContext, IPocoContext
{
    private IObjectSet<Person> persons;

    public PocoContext() : base("name=PocoContainer", "PocoContainer")
    {
        ContextOptions.LazyLoadingEnabled = true;
        persons= CreateObjectSet<Person>();
    }

    public IObjectSet<Person> Persons
    {
        get
        {
            return persons;
        }
    }

    public int Save()
    {
        return base.SaveChanges();
    }
}

Интерфейс выглядиткак это:

public interface IPocoContext
{
    IObjectSet<Person> Persons { get; }

    int Save();
}

4) Наконец, я создал репозиторий, реализующий интерфейс:

public class PersonRepository : IEntityRepository<Person>
{
    private IPocoContext context;

    public PersonRepository()
    {
        context = new PocoContext();
    }

    public PersonRepository(IPocoContext context)
    {
        this.context = context;
    }

    // other methods from IEntityRepository<T>
}

public interface IEntityRepository<T>
{   
    void Add(T entity);
    List<T> GetAll();
    T GetById(int id);
    void Delete(T entity);

}

Теперь, когда я поиграюсь с этим, этот дизайн заставляет меня создать экземплярхранилище каждый раз, когда я хочу получить или изменить некоторые данные, например:

using (var context = new PocoContext())
{   
    PersonRepository prep = new PersonRepository();

    List<Person> pers = prep.GetAll();
}

Почему-то это просто неправильно и, с другой стороны, ошибочно, просто создание экземпляра каждого хранилища в производном контексте не ощущаетсяслишком хорошо, потому что из-за потенциально инстанцирующих объектов мне это может вообще не понадобиться.

Какие-нибудь советы, как сделать этот дизайн звучащим?Должен ли я оставить это таким образом?Любые вещи, которые я должен добавить или избежать вообще, делая это?

Ответы [ 3 ]

2 голосов
/ 05 августа 2011

Я не понимаю эту часть:

using (var context = new PocoContext())
{   
    PersonRepository prep = new PersonRepository();

    List<Person> pers = prep.GetAll();
}

Почему вы создаете контекст во внешней области видимости, если вы вызываете конструктор хранилища, не передавая контекст в качестве параметра?Использование нескольких контекстов только усложнит ситуацию.Также какой смысл создавать интерфейс для репозитория и пытаться его скрыть, если ваш внешний блок просто создаст экземпляр класса?

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

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

Что ж, это можно довольно легко решить с помощью ленивой инициализации:

private SomeRepositoryType _someRepository
public SomeRepositoryType SomeRepository
{
    get { _someRepository ?? (_someRepository = new SomeRepositoryType(context)) }
}

Но я бы не стал помещать это в сам контекст.Я бы, вероятно, использовал это в некоторой фабрике доступа к данным, потому что она должна быть вне контекста, и передача одной фабрики в виде внедрения в классы / методы с использованием нескольких репозиториев проще.

Кстати. какое значение вы получите от использования репозитория?

1 голос
/ 05 августа 2011

Если вы используете POCO для создания модели вашей базы данных, можете попробовать EF Code First?ИМХО использование Code First более понятно, чем создание модели EDMX в конструкторе.

0 голосов
/ 05 августа 2011

Используйте инъекцию зависимостей, используя любой контейнер, такой как Castle Windsor, AutoFac и т. Д., Предоставляя для каждого объекта контекст объекта.

...