Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在干净的体系结构中实现业务逻辑的混乱_C#_Asp.net Mvc_Clean Architecture - Fatal编程技术网

C# 在干净的体系结构中实现业务逻辑的混乱

C# 在干净的体系结构中实现业务逻辑的混乱,c#,asp.net-mvc,clean-architecture,C#,Asp.net Mvc,Clean Architecture,在过去的两周里,我一直在尝试在一个新的应用程序中理解并实现干净的体系结构。我读过罗伯特·马丁(Robert Martin)关于这一主题的博客文章,以及许多其他文章——每一篇都有自己的观点,这让我有点困惑 请记住,我还没有掌握更深入的DDD原则,如有界上下文、值对象等,所以我试图让这个设计(以及我最初的理解)尽可能简单。我尝试使用Repository/UnitOfWork模式,下面是我的Visual Studio解决方案目前的样子(为了简洁起见,我对其进行了一些简化): 我曾想过在我的Core项目

在过去的两周里,我一直在尝试在一个新的应用程序中理解并实现干净的体系结构。我读过罗伯特·马丁(Robert Martin)关于这一主题的博客文章,以及许多其他文章——每一篇都有自己的观点,这让我有点困惑

请记住,我还没有掌握更深入的DDD原则,如有界上下文、值对象等,所以我试图让这个设计(以及我最初的理解)尽可能简单。我尝试使用Repository/UnitOfWork模式,下面是我的Visual Studio解决方案目前的样子(为了简洁起见,我对其进行了一些简化):

我曾想过在我的
Core
项目中实现
usecaseholders

public class CourseListHandler
{
    private readonly IUnitOfWork _uow;

    public CourseListHandler(IUnitOfWork uow)
    {
        _uow = uow;
    }

    public List<CourseNameResponseModel> Execute()
    {
        using (_uow)
        {
            return _uow.Courses
                .GetAll()
                .Select(s => new CourseNameResponseModel() {
                    Id = s.Id,
                    Name = s.Name,
                    Level = s.Level
                })
                .OrderBy(o => o.Name)
                .ToList();
        }
    }
}
公共类CourseListHandler
{
私人只读IUnitOfWork;
公共课程讲师(IUnitOfWork uow)
{
_uow=uow;
}
公共列表执行()
{
使用(_uow)
{
返回u uow.Courses
.GetAll()
.Select(s=>newcourseNameResponseModel(){
Id=s.Id,
Name=s.Name,
标高=s.标高
})
.OrderBy(o=>o.Name)
.ToList();
}
}
}
然后将其注入到相关的控制器类中,并在其中一个操作方法中调用。我选择使用UnitOfWork,因为我觉得如果需要的话(将来也会这样),它将允许我在一个事务中处理多个存储库对象

问题:

  • 我明白这是主观的,但我的做法对不对?你建议我改变什么,或者换个角度思考
  • 在使用UnitOfWork以及将业务逻辑外包给另一个服务/处理程序方面,我是否抽象得太多了
  • 我是否处理了正确的对象,我是否这样做正确
  • 上面的
    CourseListHandler
    只处理从存储机制获取课程简化列表的一个用例。考虑到这是针对API的,控制器(端点)中的每个操作都可能有许多用例处理程序,并且需要注入控制器的UseCaseHandler类的数量将变得非常大。我知道坚实的原则告诉我们,在这种情况下,一个班级应该只负责做一件事,但这不被认为是“过度工程”吗
  • 源于第4节,拥有一个“服务”类而不是一个UseCaseHandler不是更好吗?UseCaseHandler具有多个方法,可以满足给定控制器中每个潜在操作的需要
  • 我知道这些都是非常业余的问题,是的,我应该更多地阅读它,但老实说,我读得越多,我就越会发现在实现清洁架构方面有着巨大的不同。作为StackExchange会员,您在这方面的见解对我来说是非常宝贵的,我非常感谢


    这不是一个.NET核心解决方案-它使用的是.NET framework 4.7,我计划在DI/IoC中使用Unity。

    哇,太多了,让我试着按顺序回答这些问题

  • 我认为总的来说,你比大多数人都有更好的想法。我会查看您的核心项目,并尝试将您的域模型定义为实体或值对象。当然,您可能已经在做这件事,而没有查看我无法评估的代码。 A.此外,我希望您的API拥有您的数据传输对象。我不希望这些都在你的核心项目中

  • 如果您使用的是C sharp,并且您已经在使用实体框架,那么是否抽象出工作单元模式的想法我见过人们反复讨论。如果您决定使用另一个ORM(对象关系映射器),那么您自己实现工作单元模式可能没有什么好处那么,自己将其抽象并不会将您的项目与实体框架或任何其他ORM联系起来。
    A.抽象到一个服务可能是正确的,这取决于具体情况。我经常发现,我可以将我的许多逻辑放在域模型本身中。在这些情况下,域模型知道它们可以保存一些东西,就像学生可以向自身添加类一样,但实现这一点并不是域模型所关心的问题,它只是在一个事件中广播说John Smith添加了代数级别3。您的存储库应该设置为能够正确截取和保存该事件

  • 我看不到你的一次性计划。所以我不知道你做的是否正确。但一般来说,您的存储库应该确保您的数据库上下文已被处理,这是正确的,只要确保在您实现接口时,它实际上正在这样做
  • 你的第四个问题与固体设计原则有关,如果你在他的书《干净的克隆》或他的大部分YouTube视频中跟进,鲍勃叔叔通常会给出一个理解,那么我觉得大多数人在这个主题上教的是什么。他的论点并不是说一个类只需要做一件事,而是只需要对一个人负责,所以让一个学生存储库添加学生、带走学生、更新学生和精英学生显然是可以的,你不需要为这些情况中的每一个创建单独的类或处理程序,只需要不同的方法。他的论点是,在一个企业中,最终有一个人可以对代码进行更改,并确保每个类基本上都有一个主类。再看一看固体设计的例子,要么鲍勃叔叔讲了干净的建筑,要么看了他在YouTube上的一段视频
  • 是的,我认为在这种情况下,提供服务是正确的。您还可以查看工具“med”
    public interface IUnitOfWork : IDisposable
    {
        ICourseRepository Courses { get; }
        IStudentRepository Students { get; }
        int Complete();
    }
    
    public class CourseListHandler
    {
        private readonly IUnitOfWork _uow;
    
        public CourseListHandler(IUnitOfWork uow)
        {
            _uow = uow;
        }
    
        public List<CourseNameResponseModel> Execute()
        {
            using (_uow)
            {
                return _uow.Courses
                    .GetAll()
                    .Select(s => new CourseNameResponseModel() {
                        Id = s.Id,
                        Name = s.Name,
                        Level = s.Level
                    })
                    .OrderBy(o => o.Name)
                    .ToList();
            }
        }
    }