3

I was looking at a project recently, which contains the following Visual Studio projects:

App.Web
App.Core
App.Infrastructure

The Repository interfaces were contained in the Core project and the Repository classes (implementations) were contained in the Infrastructure project. Why would you put the Infrastructure interfaces in a separate project? The client code (or IOC) has to do this:

Core.ICustomer Repository = new Infrastructure.CustomereRpository()

What is the benefit of doing this?

If I introduced an application service (so that multiple clients can be introduced), then would the interfaces be held in the same place i.e. the core?

I have read questions like this: https://stackoverflow.com/questions/13846209/where-to-define-the-interfaces-for-a-repository-in-an-layered-architecture. However, I am still not clear why the interfaces are held in the Core.

I am also struggling to understand the difference between a project called: app.Core and a project called: app.Domain. I am wandering if app.Core contains more than the domain?

3

Any repository class MUST reference the core project in order to return the Models it contains.

Therefore, it's a sensible place to put the repository Interface.

Furthermore Business logic classes may require an instance of a IRepository to function.

If they had to reference an infrastructure dependent project to do so you would get circular references. So again, the core or models project is a good choice.

Now if you add more service projects of isolated business logic, with potential multiple concrete implementations where you put the interface for that service is an interesting question.

  • core: practical and easy, but now you have to update the core library every time you think of a new service.

  • myService: practical and easy, but unsuitable for future expansion to a second concrete implementation

  • myServiceInterface: a weird floating project with one file. not pretty

  • myBigInterfaceLibrary: a weird floating project you have to update all the time.

Normally I go with either core or myService. you can always move from myService to myServiceInterface later if required.

Repositories are a somewhat special case in that you know you are going to have them and you know they are going to be infrastructure dependent right at the begining of the project

  • Thanks. that makes sense. +1. I guess they should be held in the core project even if I introduce an application service? – w0051977 Jul 15 '17 at 14:13
  • Also, why have a project called app.core containing domain classes instead of app.domain? I believe the term was cooked in the onion architecture. – w0051977 Jul 15 '17 at 14:15
  • core/domain/models its all questionable naming. But not sure there is a consensus on a 'good' one – Ewan Jul 15 '17 at 14:59
  • What if I introduce an application service in it's own project? Would the interfaces be moved to the application service project? Thanks. – w0051977 Jul 15 '17 at 15:03
  • you mean move all your interfaces to a big interface project or move your repo interface to a random service project – Ewan Jul 15 '17 at 15:12
2

What is the benefit of doing this?

One thing to keep in mind is that the application, the domain model, and persistence each evolve at a different pace from the others. The domain is expected to be able to support multiple applications; and you are supposed to be able to revise the implementation within the domain frequently -- but persistence generally evolves more slowly, because we don't throw away the accumulated state each time we update the model.

The Repository interfaces were contained in the Core project and the Repository classes (implementations) were contained in the Infrastructure project.

Well, the repository interface is the contract that defines the agreement between the application and the domain model (which is itself encapsulating the persistence component behind it). So it makes a certain amount of sense that those interfaces are either in core or in application -- if you aren't going to pull them out separately, and you are expecting to support multiple applications, core is the natural home for them.

As for where the implementations go, that gets a bit trickier. The entities and values in your domain model have two logically distinct representations - the one you see in memory, and the one you see in your durable store (think objects in memory vs rows in an RDBMS).

What Evans described in the blue book is that the role of the repository is to provide the illusion that the aggregates all live in memory. So it's reasonable to think of the repository as a service provider interface, with the infrastructure component as the service provider responsible for deciding how to serialize/deserialize data to/from the book of record.

CQRS helps to make this separation clear; because the read and write use cases differ, the roles defined for the repository are also different. In particular, it's not surprising that we might decide that a particular use case wants a specific kind of data store -- a document store for providing cached representations of views, or a graph database for fast queries of a social network.

In this sort of a design, that change is easy -- you just swap out the specific persistence implementation, and the changes to the applications and the domain models are minimal; the infrastructure changes a lot (complete replacement within that use case), and the composition root a little (replacing one persistence module with another), but the model and the application are unaffected by the change.

It can, of course, get more intricate: in event sourced systems, you normally have a representation of events in your durable event store, which may or may not align with the representation of events in memory, which in turn are distinct from the representations of the aggregates that you use when computing new events. In this sort of system, the persistence component would normally be concerned with writing events to and from your event store, where the translations of event histories to and from the aggregates would live in the domain model (ie: core).

  • Hell, VoiceOfUnreason you always so acurate in your answers. +1. Write a book!! – Laiv Jul 16 '17 at 9:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.