如何在N层应用中实现IDependencyResolver?

How to implement IDependencyResolver in an N-tier layer application?

我有一个三层应用程序。每个部分都依赖于我的解决方案的另一部分。我曾经在 MVC 项目中实现 IDependencyResolver。这是一种错误的方式,因为它会导致违反分层的架构规则。我的 MVC 项目引用了 DAL 层。这是一种糟糕的编码习惯。我知道我可以创建一个单独的 class 库项目。它将引用我的解决方案的任何其他项目。它将解决所有依赖关系。我听说这不是最好的方法。有一个更好的办法。我的解决方案的每个项目都应该解决它拥有的依赖项。我不明白如何把它们放在一起。所以我找到了这篇有用的文章:Dependency Injection Best Practices in an N-tier Modular Application 但它似乎太难太复杂了。还有别的办法吗?我有类似的解决方案结构。 UserRepository returns 一个请求的用户。

public interface IUserRepository
    {
        IEnumerable<UserEntity> GetAll();
    }

    public class UserRepository : IUserRepository
    {
        public IEnumerable<UserEntity> GetAll()
        {
            // some code
        }
    }

UserService 可以有一些不同的依赖关系。

public interface IUserService
    {
        IEnumerable<UserModel> GetAll();
    }

    public class UserService : IUserService
    {
        private readonly IUserRepository userRepository;
        private readonly ISecondRepository secondRepository;
        private readonly IThirdRepository thirdRepository;

        public UserService(IUserRepository userRepository, ISecondRepository secondRepository, IThirdRepository thirdRepository)
        {
            this.userRepository = userRepository;
            this.secondRepository = secondRepository;
            this.thirdRepository = thirdRepository;
        }

        public IEnumerable<UserModel> GetAll()
        {
            // some code
        }
    }

最后 UserController 构造函数可能有很多不同的依赖项。

我的问题是什么是解决这些依赖关系的正确和最简单的方法,避免违反架构规则?

就像你说的,你可以创建额外的层来组合依赖项,这称为组合根 Check this SO question。 在您的情况下,组合根是 MVC 项目。 从我的角度来看,引用 DAL 并不是什么坏习惯。 当我们谈到依赖关系时,应该画一条线。对我来说,当我们谈论依赖关系时,dll 引用并不重要,而是使用的类型(接口或具体)。如您所知,DI 依赖于具有实际价值的抽象。所以你的代码仍然可以,只要你只依赖于 DAL 中的接口。

在实践中,当 dll 依赖关系变得太复杂时,我使用了额外的项目作为组合根。

关于你的问题关于层应该如何解决它们的依赖关系。我不确定这是否是你的意思,但在 DDD 中有练习你的 BLL 在它自己的层中定义基础设施接口(如存储库)。这样,依赖图就受到了尊重。现在,基础结构层 (DAL) 您只需定义 BLL 提供的接口的具体实现,再次在组合根中连接所有内容。

第一种方法,基础设施层定义接口,实现的优点是无依赖性,适合跨不同项目重用。但是请记住,在大域中工作时,这有时可能会导致代码无法维护。

第二种方法 作为 DDD,最​​重要的是域,所以一切都适用于域。根据我的经验,在域周围拥有结构良好的层是最好的选择。此方法使您的代码更明确地说明您为域解决的问题。 不知道自己表达的是否正确

作为最后的说明,如果将其用作学习经验,我会建议您使用 DDD 方法。学习新东西是最好的选择。

我不是该领域最有经验的人。 我做了大约 3 年的程序员,主要从事中型项目,所以我的意见并不可靠 ;]