【问题标题】:Onion Pattern .Net Core Related Entities洋葱模式 .Net Core 相关实体
【发布时间】:2019-01-29 16:44:56
【问题描述】:

我正在尝试了解 .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);
                }

【问题讨论】:

    标签: asp.net-core onion-architecture


    【解决方案1】:

    链接的存储库高度过度设计,坦率地说天真设计。创建多个项目不等于“洋葱架构”,而且到处都是依赖关系。洋葱架构的整个概念是拥有 true 层。输入在层之间流入和流出,并且没有交叉。看起来贡献者正在尝试 CQRS,但失败得相当惨。

    至于您的具体问题,这种特殊设置在使用存储库时存在致命缺陷。不幸的是,太多的开发人员都这样做了,贡献者没有意识到当使用像 EF 这样的 ORM 时,你的数据层。在此之上创建一个单独的抽象只会导致问题,除非您复制 EF 所做的所有事情,例如连接、更改跟踪、对象修复等。当然,当您这样做时,您基本上只是重新实现 EF。在您的应用程序和 EF 之间放置一个简单的存储库之类的东西,本质上只是限制了您可以对数据执行的操作,当然,在这种情况下,您的问题是在没有大量过度查询的情况下无法加入相关实体.

    如果您想真正抽象您的数据依赖关系,CQRS 和微服务模式是您的最佳选择。 CQRS 是一个非常复杂的主题,但它本质上归结为构建执行特定操作的“命令”,同时着眼于创建事件驱动模型。我鼓励你更多地研究这个主题,但我会说,正确设置它的努力只有在大型企业级应用程序中才有意义。鉴于微服务模式的兴起,这一点尤其正确。

    微服务本质上是微型 API。它们通常作为基于 REST 的 Web API 实现,但不一定非要如此。无论如何,这个想法是您有执行特定任务的端点返回特定数据。他们应该专注于应用程序功能的离散单元。例如,电子商务网站可能有产品服务、购物车服务、支付处理/结账服务、订单服务等。每个组件都利用这些微服务中的一个或多个来完成某些任务。通常涉及一个或多个 API 网关来协调多个微服务的活动。这听起来可能有点复杂,但实际上设置起来相当容易,尤其是在您已经熟悉构建基于 REST 的 API 的情况下。最困难的提升是协调服务以完成特定工作。这种模式还具有高度可扩展性的好处。由于每个微服务都是离散和抽象的,因此您可以轻松地进行负载平衡和/或创建集群。而且,在云环境中,您可以根据流量轻松扩大或缩小规模。如果您的网站在某个领域受到重创,您只需启动更多正在运行的微服务实例,当流量停止时,您将它们重新启动。

    最后,我要给你一些建议,我必须努力学习:从小处着手。有一种动力想要“正确”地做事,因此从一开始就实现各种模式和架构风格。这样做的结果是,您通常会陷入模式地狱,并且从未真正构建任何东西,即您有一个非常复杂的设置,需要您花费数周或数月的时间来开发,而实际上没有任何实际用途为它展示。

    相反,应尽可能以最直接、最简单的方式构建最小的功能单元。然后,继续下一个。在每次迭代之后,您应该有一些实际工作的东西。你一直这样做,直到你构建了你的核心功能。它可能不漂亮,但它可以完成工作。然后,你重构:如果你重用了一些代码,就把它们分解掉。如果您有相似但略有不同的代码,请先找到对其进行概括的方法。随着事物开始被抽象,您可能会发现需要创建类库等。随着时间的推移,您最终可能会构建一个包含各种层和抽象的真正复杂的设置,但这不是 100% 的起点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-25
      • 2020-07-26
      • 1970-01-01
      • 2011-10-09
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多