Onion Pattern .Net Core Связанные объекты - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь понять шаблон архитектуры Onion в ядре .net.Учитывая приведенный ниже пример проекта Github, как бы вы включили связанные объекты?Например, как в GamesController вы бы также возвращали связанные объекты платформы?Поскольку каждая служба связана с хранилищем сущностей

https://github.com/CubicleJockey/OnionPattern

    /// <summary>
    /// Get a list of all games.
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [Route("all")]
    public IActionResult Get()
    {
        return ExecuteAndHandleRequest(() => GameRequestAggregate.GetAllGamesRequest.Execute());
    }



    public class GameRequestAggregate : BaseRequestAggregate<Domain.Game.Entities.Game>, IGameRequestAggregate
        {

            public GameRequestAggregate(IRepository<Domain.Game.Entities.Game> repository, IRepositoryAggregate repositoryAggregate) 
                : base(repository, repositoryAggregate)  {}

            #region Implementation of IGameRequestAggregate

            private ICreateGameRequest createGameRequest;
            public ICreateGameRequest CreateGameRequest => createGameRequest ?? (createGameRequest = new CreateGameRequest(Repository, RepositoryAggregate));

            private IDeleteGameByIdRequest deleteGameByIdRequest;
            public IDeleteGameByIdRequest DeleteGameByIdRequest =>deleteGameByIdRequest ?? (deleteGameByIdRequest = new DeleteGameByIdRequest(Repository, RepositoryAggregate));

            private IGetAllGamesRequest getAllGamesRequest;
            public IGetAllGamesRequest GetAllGamesRequest => getAllGamesRequest ?? (getAllGamesRequest = new GetAllGamesRequest(Repository, RepositoryAggregate));

            #endregion
        }




public class GetAllGamesRequest : BaseServiceRequest<Domain.Game.Entities.Game>, IGetAllGamesRequest
    {
        public GetAllGamesRequest(IRepository<Domain.Game.Entities.Game> repository, IRepositoryAggregate repositoryAggregate) 
            : base(repository, repositoryAggregate) { }


        #region Implementation of IGetAllGamesRequest

        public GameListResponse Execute()
        {
            Log.Information("Retrieving Games List...");
            var gameListResponse = new GameListResponse();
            try
            {
                var games = Repository.GetAll()?.ToArray();

                if (games == null || !games.Any())
                {
                    var exception = new Exception("No Games Returned.");
                    Log.Error(EXCEPTION_MESSAGE_TEMPLATE, exception.Message);
                    HandleErrors(gameListResponse, exception, 404);
                }
                else
                {
                    gameListResponse = new GameListResponse
                    {
                        Games = games,
                        StatusCode = 200
                    };
                    var count = games.Length;
                    Log.Information("Retrieved [{Count}] Games.", count);
                }

1 Ответ

0 голосов
/ 29 января 2019

Связанный репо - высоко чрезмерно спроектирован, и откровенно наивно спроектирован при этом.Создание нескольких проектов не равняется «луковой архитектуре», и повсеместно возникает зависимость.Вся концепция луковой архитектуры состоит в том, чтобы иметь истинных слоев.Входные потоки входят и выходят между слоями, и пересечения нет.Похоже, что участник делает удар в CQRS, но терпит неудачу довольно неудачно.

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

Если вы хотите по-настоящему абстрагировать свою зависимость от данных, лучше всего использовать шаблоны CQRS и микросервисов.CQRS - очень сложная тема, но по сути она сводится к созданию «команд», которые делают конкретные вещи, а также к созданию модели, управляемой событиями.Я призываю вас больше изучить эту тему, но я скажу, что усилия по правильной настройке действительно имеют смысл только в больших корпоративных приложениях.Это особенно верно, учитывая рост числа микросервисов.

Микросервисы - это по сути крошечные API.Они обычно реализуются как веб-API на основе REST, но не обязательно должны быть.Несмотря на это, идея заключается в том, что у вас есть конечные точки, которые выполняют конкретные задачи и возвращают конкретные данные.Они должны сосредоточиться на отдельной единице функциональности приложения.Например, сайт электронной коммерции может иметь услугу продукта, услугу корзины, услугу обработки / оплаты, услугу заказа и т. Д. Каждый компонент использует один или несколько из этих микросервисов для выполнения некоторой задачи.Обычно для координации работы нескольких микросервисов используется один или несколько API-шлюзов.Это может показаться немного сложным, но на самом деле его довольно легко настроить, особенно если вы уже знакомы с созданием API на основе REST.Сложнее всего координировать услуги для выполнения конкретной работы.Этот шаблон также дает преимущество высокой масштабируемости.Поскольку каждый микросервис является дискретным и абстрактным, вы можете легко балансировать нагрузку и / или создавать кластеры.А в облачной среде вы легко увеличиваете или уменьшаете масштаб в зависимости от трафика.Если ваш сайт забивается в одну область, вы просто раскручиваете больше экземпляров микросервисов в игре, а когда трафик уменьшается, вы вращаете их обратно.

Наконец, я оставлю вас с советом.пришлось учиться трудным путем: начинать с малого.Есть стимул хотеть делать вещи «правильно» и, следовательно, внедрять всевозможные шаблоны и архитектурные стили с самого начала.Результатом этого является то, что вы, как правило, застреваете в адском паттерне, и никогда на самом деле не строите ничего, т. Е. У вас есть очень сложная установка, на разработку которой у вас ушли недели или месяцы, и на самом деле ничего для реального использованияпокажи это.

Вместо этого создайте наименьшую функциональную единицу самым простым и простым способом.Затем перейдите к следующему.После каждой итерации у вас должно быть что-то, что на самом деле работает .Вы продолжаете делать это до тех пор, пока не создадите свою основную функциональность.Это может быть не красиво, но это делает работу.Затем вы делаете рефакторинг: если вы повторно использовали биты кода, отсеивайте их.Если у вас есть похожий, но немного другой код, сначала найдите способы его обобщить.Как только вещи начнут абстрагироваться, вы можете обнаружить необходимость создания библиотек классов и тому подобного.Со временем вы можете создать действительно сложную установку со всеми видами слоев и абстракций, но это не на 100% то, с чего вы начинаете.

...