Слой сервиса, используя рамки сущности 6.2


Я хотел бы, чтобы вы ознакомились часть моего склада приложении Service Layer чтобы быть точным. Архитектура программы является:

ДБ --> .Данных (DbContext и/организаций в EF) --> .ServiceLayer (бизнес) --> службы WCF

У меня есть шаблоны РЕПО/Ву реализованных в данных (DbConext эф был построен в). В основном ничего больше. Сырые dbset объектов и субъектов. Вся магия делается в бизнес-слой, очевидно.

В бизнес-слой, я реализовал кучу сервисов, как PurchaseOrderService или ReceivingService. Дело в том, что эти услуги могут быть использованы службу WCF непосредственно и сами по себе бизнес. Например GetItemStatus можно использовать службу WCF с таким же названием "GetItmeStatus" или он может быть использован GetItemQuantity сервис (так как если пункт заблокирован, кол-во 0). Позвольте мне разместить код:

public class ItemService
{
    IContextFactory ContextFactory { get; set; }

    public ItemService(IContextFactory contextFactory)
    {
        ContextFactory = contextFactory;
    }

    public ItemStatus GetItemStatus(int itemId, WarehouseContext warehouseContext = null)
    {
        ItemStatus returnedItemStatus = ItemStatus.New;

        //DBContext should be disposed only if it was created here, locally
        bool shouldBeDisposed = (warehouseContext == null);
        if (shouldBeDisposed) warehouseContext = ContextFactory.CreateWarehouseContext();

        try
        {
            returnedItemStatus = warehouseContext.Items.Where(p => p.ItemId == itemId).Status;
        }
        finally
        {
            if (shouldBeDisposed) warehouseContext?.Dispose();
        }

        return returnedItemStatus;
    }

    public int GetItemQuantity(int itemId, WarehouseContext warehouseContext = null)
    {
        int returnedQuantity = 0;

        //DBContext should be disposed only if it was created here, locally
        bool shouldBeDisposed = (warehouseContext == null);
        if (shouldBeDisposed) warehouseContext = ContextFactory.CreateWarehouseContext();

        try
        {
            if (GetItemStatus(itemId, warehouseContext) != ItemStatus.Blocked) 
            {
                returnedQuantity = warehouseContext.Items.Where(p => p.ItemId == itemId).Quantity;
            }
        }
        finally
        {
            if (shouldBeDisposed) warehouseContext?.Dispose();
        }

        return returnedQuantity;
    }
}

Конечно, в этом примере показаны два метода с той же службы. Вполне возможно, что одна служба будет создать другую службу и вызывает его функцию.

Я хочу, чтобы вы, чтобы посмотреть, как я веду дополнительный параметр контекста, try finally блок вместо довольно using блок. Таким образом, я не должен создать DbContext, который во время каждой поездки на базу. Я могу создать DbContext и в контексте. Когда я должен получить ItemStatus (только ItemStatus) из WCF (или любой другой клиент) слой.. я могу сделать это! и DbContext, который будет создаваться и уничтожаться.

Как вам это нравится? Спасибо!



1125
2
задан 30 января 2018 в 05:01 Источник Поделиться
Комментарии
1 ответ


Как вам это нравится?

Не нравится мне это ;-)

Потому что...


  • Это хранилище и должен быть назван ItemRepository

  • Если вы не можете доказать (при грамотном результаты профайлера), что повторно использовать контекст имеет лучшую производительность меня не волнует. Из-за этого opmization ваш API будет более сложным и запутанным. Смотрите производительности (сущности рамок) на самом деле вы могли бы выиграть больше производительности при отключении отслеживания изменений, чем за счет повторного использования контекста.

  • В ContextFactory недвижимость public и это был сеттер. Почему? Это уже установить через конструктор. Сделать это либо частное поле или удалить конструктор, потому что конструктор мне сообщает, что это значение является обязательным. Для этого класса, однако это так. Обязательны для создания, но он может быть установлен в null после создания ItemService. Это очень сложно.

  • Вам не нужны никакие вспомогательные переменные returnedItemStatus или returnedQuantity. Просто возвращать значение, где вы получите его.

  • ItemStatus.New еще одна запутанная вещь. Если я попытаюсь GetItemStatus и он не существует, то я надеюсь, что он либо бросит, либо вернуть статус, который говорит мне, что этот пункт фактически не существует. Как это может быть New если бы не нашли? То же самое касается и другой способ. Если элемент не существует, я ожидаю либо исключение, либо -1 для количества, которое сообщает мне, что элемент не существует. Говорю 0 за то, что это не было просто неправильно. Это заставляет меня думать, что это мог быть или был там, но уже продан. Так ли 0 значит, вам не предлагают его вовсе, или она сейчас не в наличии? 0 не очень полезный результат в этом случае. Вам лучше различать оба случая.

  • Здесь я сделал обзор вашего кода, потому что вы не можете вернуться в один Status из этого запроса .Where(p => p.ItemId == itemId).Status что заставляет меня думать, что это не ваш реальный сервис...

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

4
ответ дан 30 января 2018 в 06:01 Источник Поделиться