复杂服务层IoC最佳实践

kei*_*itn 6 c# asp.net-mvc design-patterns inversion-of-control

我正在开发一个 MVC 应用程序,我正在使用 Unity 进行 IoC。我的应用程序基本上由 UI 层、服务层和存储库层组成。

我的典型控制器是:

public class TestController : Controller
    {
        private ITestService testServ;

        public TestController(ITestService _testServ)
        {
            testServ= _testServ;
        }

    public ActionResult Index()
    {
        testServ.DoSomething();
        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

没有什么异常,我的每个控制器都注入了一个服务对象。我的服务层对象执行复杂的业务规则,聚合来自许多不同存储库的信息。通过使用 IoC,我发现我的构造函数看起来过于复杂,但由于该服务需要访问许多存储库,我看不到任何解决此问题的方法。

我的服务层中的典型类如下所示:

public class TestService : ITestService
    {
        private ITransactionRepository transRepo;
        private IAccountRepository accountRepo;
        private ISystemsRepository sysRepo;
        private IScheduleRepository schRepo;
        private IProfileRepository profileRepo;

        public TestService(ITransactionRepository _transRepo;
                           IAccountRepository _accountRepo;
                           ISystemsRepository _sysRepo;
                           IScheduleRepository _schRepo;
                           IProfileRepository _profileRepo)
        {
            transRepo = _transRepo;
            accountRepo = _accountRepo;
            sysRepo = _sysRepo;
            schRepo = _schRepo;
            profileRepo = _profileRepo;
        }

        public DoSomething()
        {
            //Implement Business Logix
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的几个服务层对象需要 10 个或更多存储库。我的存储库使用实体框架,其中每个存储库类公开底层数据存储中的一个表。

我正在寻找有关上述情况下最佳实践的一些建议。

tak*_*gen 2

以下是简化(和减少)依赖性的一些步骤:

  1. 将您的服务拆分为单独的服务并将它们注入到您的控制器中。这将减少服务的依赖数量。缺点是您需要向控制器注入更多依赖项。当控制器变得复杂时,下一步是拆分控制器。记住单一职责原则

  2. 看一下有界上下文 模式:您可以尝试对通常在单个上下文中聚集的实体进行分组,并将该上下文注入到服务中,而不是注入数十个存储库:

    public class TestService : ITestService
    {
        private readonly ITestData testData; // represents a bounded context
    
        public TestService(ITestData testData)
        {
            this.testData = testData;
        }
    
        public void DoSomething()
        {
            this.testData.Transactions.Add(...); //It gives you access to Transactions repository
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)