2015-02-05 2 views
3

ВведениеEF N-Tier Архитектура

Мы требуем, чтобы создать приложение для п-го уровня, как мы хотели бы поделиться нашим BL над нескольких платформами и писать только наши DAL один раз. Я уже провел некоторые исследования по этому вопросу.

Как можно прочитать здесь, в сообщении Davide Piras: MVC3 and Entity Framework каждое решение VS должно иметь по крайней мере 4 слоя. Все идет нормально.

Он также утверждает, что проект DAL является единственным проектом, которому разрешено даже знать, что используется EF.

Вопрос 1:

Я предполагаю, что интерфейсы проекта «Интерфейсы» являются 1 на 1 представление моих EF сущностей а, я правильно на это? Кроме того, эти интерфейсы должны использоваться как типы между разными слоями?

Вопрос 2:

MSDN советы о том, что время жизни DbContext должен быть один контекст для каждого запроса на WebApps и один контекст каждой формы в проекте WPF или WinForms. Итак, как я могу достичь этого, не добавляя «System.Data.Entity» к моему графическому интерфейсу?

Thnx заранее!

+0

Thnx для downvote, если я что-то пропустил, учтите, что я прокомментирую .. Я поставил немного энергии и времени, чтобы задать эти вопросы. –

ответ

2

Прежде всего НЕ ДЕЛАЙТЕ !!! делитесь своим DAL на нескольких платформах. Поделитесь своим BL, который использует DAL. Пока ваш BL представляет собой решение ваших требований к приложениям, вам не нужно раскрывать свой DAL и, пожалуйста, нет. Кроме того, выявление DAL имеет недостаток, заключающийся в том, что вы обнаруживаете больше уязвимостей для хакеров, а прямой доступ к DAL обеспечивает механизм btpass для вашей бизнес-логики, элементов управления и валидности в вашем BL.

Ответ 1: Возможно, это не понадобится. Думая о SOA, я предлагаю использовать DTO. Либо они являются сущностями, либо более сложными, составными классами нескольких и/или частичных объектов. Если вы используете сущности, это дает вам больше гибкости для предоставления информации через BL (вы можете отправлять несколько частей данных одновременно одним вызовом метода) и скрывает вашу сущность (также структуру БД) от сторонних пользователей, обеспечивающих лучшее чувство безопасности.

Ответ 2: Опять же, думая с SOA, не создавайте свои методы BL/Service в соответствии с вашим пользовательским интерфейсом. BL (как следует из названия) предоставляет данные в соответствии с «как делается работа« не »как работа выполняется пользователем на экране». И если вы попытаетесь управлять своими данными из графического интерфейса, вы также начнете нарушать архитектуру N-уровня. НЕ ДЕЛАЙТЕ !!! использовать любой тип данных данных и/или методы вне DAL. Это будет истинное использование слоев.

С уважением.

+0

Thnx для вашего быстрого ответа! Извините, я не хотел делиться DAL, как в том, чтобы разоблачить его для других графических интерфейсов, но писать только один раз! Виноват. –

+0

Я рад, если помогу. – user3021830

+0

Да, вы помогли;). Я запомню как ответ через пару часов, я все еще жду большего мнения, и я думаю, что люди более нетерпеливы, когда вопрос остается без ответа. –

3

Вы должны использовать Unit of Work и Repository шаблоны с зависимой конструкцией впрыска, например StructureMap или Unity.

В принципе, то, что вам нужно сделать, это создать интерфейсы:

public interface IUnitOfWork 
{ 
    void SaveChanges(); 
} 

public interface IRepository<TItem> 
{ 
    TItem GetByKey<TKey>(); 

    IQueryable<TItem> Query(); 
} 

Теперь в вашем DbContext класса реализуют интерфейсы выше, и где-то в вашей бизнес-уровне зарегистрировать реализацию интерфейсов:

public void RegisterDependencies(Container container) 
{ 
    // Container is a Structure Map container. 
    container.ForRequestedType<IUnitOfWork>() 
     .CacheBy(InstanceScope.HttpContext) 
     .TheDefaultConcreteType<DbContext>();  
} 

См. StructureMap Scoping Docs о том, как настроить область действия экземпляра.

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

public class SomeService 
{ 
    public SomeService(IRepository<SomeItem> repository, IUnitOfWork unitOfWork) 
    { 
     this.repository = repository; 
     this.unitOfWork = unitOfWork; 
    } 

    public void MarkItemCompleted(int itemId) 
    { 
     var item = repository.GetByKey(itemId); 
     if(item != null) 
     { 
      item.Completed = true; 
      unitOfWork.SaveChanges(); 
     } 
    } 
} 

Теперь, скрытие создания служб за заводом:

public class ServiceFactory 
{ 
    private readonly Container container;// = initialize the container 

    public TService CreateService<TService>() 
    { 
     return container.GetInstance<TService>(); 
    } 
} 

И в вашем слое GUI вызовите только методы классов обслуживания, созданные через ServiceFactory; если ваш графический интерфейс является проектом ASP.NET MVC, вам не нужно создавать класс ServiceFactory - вы можете получить от DefaultControllerFactory и переопределить метод GetControllerInstance. См. Пример the answer here.

+0

Thnx для вашего четкого ответа! Это очень полезно. Я уже сталкивался с шаблоном Repositry и UOW. Я думаю, что реализация Repo должна быть в DAL, я прав? Thnx снова. –

+0

@MarkRijsmus, да, это должно быть в доступе к данным. – RePierre

Смежные вопросы