title: Can Domain Services access Repositories?
body: <p><strong>Can Domain Services access Repositories? Or they should work on Aggregates/Entities passed to them by Application Services?</strong> </p>
  
  <p>Consider two code samples of the same business operation - money transfer. As first step, I alter account balances. Then I obtain the notification email and send the notification. I know, I should probably abstract the way notifications are sent (email, SMS, carrier pigeon), but for simplicity's sake let's assume that we support only emails by now.</p>
  
  <p><strong>Variant 1</strong> uses repositories inside the domain service. <strong>Variant 2</strong> resolves dependencies in the application service and passes them to the <code>TransferDomainService</code>.</p>
  
  <p>In this  example the operation is simple (subtract money from one account and add it to another). But if there would be more business rules involved (possible requiring access to more aggregates)? If variant 2 is applied, then the application service must have the knowledge what exactly the domain service requires. If variant 1 is chosen, then the domain service asks repositories for what it requires to perform its task.</p>
  
  <p>(Notes about snippets: Groovy code to strip verbosity of Java. DDD building blocks included in names)</p>
  
  <p><strong>Variant 1</strong></p>
  
  <pre class="lang-groovy prettyprint-override"><code>class TransferApplicationService {
      def transferDomainService
      def customerDomainService
      def emailNotifierInfrastructureService
  
      def transfer(fromAccount, toAccount, amount) {
          transferDomainService.transfer(fromAccount, toAccount, amount)
          def email = customerDomainService.accountNotificationEmail(toAccount)
          emailNotifierInfrastructureService.notifyAboutTransfer(email, amount)
      }
  }
  
  class TransferDomainService {
      def accountRepository
      def transfer(fromAccount, toAccount, amount) {
          def from = accountRepository.findByNumber(fromAccount)
          def to = accountRepository.findByNumber(toAccount)
          to.decreaseBalance(amount)
          from.increaseBalance(amount)
      }
  }
  </code></pre>
  
  <p><strong>Variant 2</strong></p>
  
  <pre class="lang-groovy prettyprint-override"><code>class TransferApplicationService {
      def accountRepository
      def transferDomainService
      def customerDomainService
      def notifierInfrastructureService
  
      def transfer(fromAccount, toAccount, amount) {
          def from = accountRepository.findByNumber(fromAccount)
          def to = accountRepository.findByNumber(toAccount)
          transferDomainService.transfer(from, to, amount)
          def email = customerDomainService.accountNotificationEmail(toAccount)
          notifierInfrastructureService.notifyAboutTransfer(email, amount)
      }
  }
  
  class TransferDomainService {
      def transfer(fromAccount, toAccount, amount) {
          to.decreaseBalance(amount)
          from.increaseBalance(amount)
      }
  }
  </code></pre>