48

The Clean Architecture suggests to let a use case interactor call the actual implementation of the presenter (which is injected, following the DIP) to handle the response/display. However, I see people implementing this architecture, returning the output data from the interactor, and then let the controller (in the adapter layer) decide how to handle it. ...


12

My guiding principle here is to ask what I consider the most important design question: What knows about what? Here's an onion diagram. It's not that much different from this: But this one shows the flow of control in and out of layers. That's important here because the flow of control dictates the order of construction if your objects are immutable. ...


12

It seems to me that most 'new' things in software architecture are old ideas refurbished and combined with new technologies or other ideas. Often these are incremental. In this case, the change that I think matters is the database is no longer the center of the design. This is not an minor change; it's pretty fundamental. So is the "onion architecture" ...


10

Layers, Onions, Ports, Adapters: it's all the same Since this article makes clear that onion is equivalent to 3 layer + application of the Dependency Inversion Principle (DIP), then the question becomes "where should I prefer to use DIP?" I'd say any non-toy project. Using DIP allows the core of your code to be more isolated, testable and maintainable. When ...


8

Q: Do you always expose a service such as IUserService to an app that consumes it? We usually do. Some times by inertia (we got used to), others for testing, but most of the time to decouple boundaries within the application. It's a common practice which brings us interesting benefits at a small cost (complexity). Services orchestrate calls between ...


7

In a discussion related to your question, Uncle Bob explains the purpose of the presenter in his Clean Architecture: Given this code sample: namespace Some\Controller; class UserController extends Controller { public function registerAction() { // Build the Request object $request = new RegisterRequest(); $request->name = $...


7

Domain Layer should only contain Business Logic. This confuses me when I read about the Onion architecture, which states that the domain layer should contain all interfaces including services and repositories Business Logic is the core responsibility of the domain layer. However, if that was strictly all the domain layer knew about, it wouldn't be able to ...


5

There is nothing at all required of you from a project/folder perspective to establish an Onion architecture, though the layers in the model do suggest natural places to put project/API boundaries. Take a look at this diagram: Now have a look at this one: Other than the shape of the diagrams, do you notice anything interesting? The only material ...


5

Overview Let's step back a little, and look at the original Onion Architecture proposed by Jeffrey Palermo. The outside skin is the interface to the external world: the user interface, the test suite (the idea is to promote TDD alike systematic tests for everything inside), and the infrastructure. Then you dig deeper inside towards the core to find ...


5

And knowing (correct me if I'm wrong) that a repository shouldn't return a DTO Theoretically, every layer (= project in your solution) should have its own DTO objects. In that sense, your repositories should return a DTO, but this is not the same DTO as the "business logic DTO". However, in reality, we don't need that much separation. The benefits do not ...


4

I'm not so sure that the onion architecture makes much sense in this case. What you can keep from the onion architecture is the principle that your application core (the translators) should be decoupled from the data access. But overall your requirement is much more like a pipeline. read -> transform -> write Now, read and write are impure (...


4

What you are looking for is called Bounded Context in DDD. Now, as you are realizing in your question, bounded contexts might share data. The best way to implement it that I saw is simply to duplicate the entities. So Accounting context has Customer, and so does Production have Customer. But even though they have same name, they have completely different ...


4

By adopting DDD and onion architecture, you have decided that database is second to your domain model. That means, there won't be anyone else doing operations on the database other than the model. If traditionalists don't like that, they should have objected to use of DDD in the first place. First thing is clear : you need the "lookup table" in the model. ...


4

The Unit of Work is the transaction. The challenge is making sure the NHibernate interfaces and classes are not referenced outside of your data access layer. The unit of work interface should not have any NHibernate references, something like: public interface IUnitOfWork : IDisposable { void Begin(); void Commit(); void Rollback(); } The ...


4

The division of specifications into "Business Rules" and "Application Rules" is always going to be somewhat arbitrary. In the abstract it might seem obvious that the Sales Report is a Use Case and compiling it in the application requires application level logic to manipulate Orders. Where as an Order is a Entity that contains Business logic. But you could ...


3

Spring Framework is a framework that supports both architectures. It has features to make database-centric architecture easier to do, but it would be a misnomer to simply classify it that way. There are several microservices built with Spring that don't use a database at all. You probably don't know about them because they are proprietary to, well, a ...


3

Onion architecture means hiding dependencies to infrastructure behind an interface. All components that use IUserService do not need to know wether the service is implemented using soap, rest, http or anything other infrastructure related. The actual UserService implementation uses a repository interface IUserRepository as implementation detail. The ...


3

The Clean Architecture does not say anything about implementing interfaces, dependencies or interactions between different use cases. Use cases are all part of the same ring. So at this part of the system, you are on your own, have to start thinking by yourself and make your own decisions about how you are going to implement things in a meaningful manner. ...


2

Domain objects stop being domain objects when they cross a process boundary. Even if the database is just a persistence store, at some point in the future the demands of the business are going to cause a change to the domaim model that is inconsistent with the persisted history, and you are going to need an anti corruption layer anyway.... That said, I ...


2

Your primary concerns are: Finding a way to make your existing IQueryable Linq queries compatible with Postgres. Working through any vendor differences in the SQL statements and database features you are using. Finding substitutes for vendor-specific capabilities that you're using in SQL Server that are not present in Postgres. For your IQueryable provider,...


2

A use case can contain either the presenter or returning data, depends on what is required by the application flow. Let’s understand few terms before understanding different application flows: Domain Object: A domain object is the data container in domain layer on which business logic operations are carried. View Model: Domain Objects are usually mapped to ...


2

Even though you said not to, I’m going to tell you that your use of ISession is an implementation detail, and should not be exposed to the domain layer. The domain should be agnostic of how (or even if) your repository is physically persisting entities. ISession, as you say, is an NHibernate specific implement detail. So how to solve? Well, your UoW ...


2

I don't know if I understand correctly your doubt, but if what you want to know is whether include or not an application service for each bound context, the answer is yes. You can create and include both an application service and all the structure of DDD architecture if it makes some sense to your solution. Each Bounded Context, can have a N-Layered ...


2

Are Services part of the Bounded Context? Yes. Contexts separate areas of potentially different meanings, and they cover the whole application completely, there is nothing "outside". What might be confusing is, that Services are actually not part of the Domain. You might think, that Domain-Driven Design is all about the Domain, but for some reason Eric ...


2

The repository should return a Domain Model. You should have a single repository per database, rather than one per table. In your case if you want both domain models in as single query then you could either Change your Domain Model so that A has a child object B Have two separate methods still, but cache the results, so that the second method called, ...


2

In my experience, if you have a use case where you want to pick different areas of your code for reusage, as shown in your example, it is preferable to have small, independent components, even if some of them might contain just one class. You already mentioned a very good reason for this in your text: restricting the impacts of change. However, there are ...


2

1) Am I going in the right direction? This is a much too broad question if you want it answered with any amount of detail. We don't know exactly what your current experience is and whether there are things worth learning here. The list you've made doesn't look wrong at first glance, but there are many ways in which you could do things wrong. I've seen ...


2

Although in this response I do not intend to dive into the ".NET architectural specifics" of your particular case, I would like to introduce the notion that perhaps your present design decisions might be "coupling" these two very-different use cases too much: Console Application WebAPI Application Consider, then, dividing the system into three parts: A "...


2

Here ADM is the right approach. There is no point returning an object with methods from a controller method. The object is immediately serialised and sent over the wire. Nothing recieves the method. The contoller actions will have shared dependencies on various services which you will want to reuse for each request. Inject these into the contoller so you ...


2

Answer to your question Taking Jeff Palermo's own explanations: Domain Services: it is interfaces who are implemented in the outer layers, since they need some services of the outer world (i.e. databases). The first layer around the Domain Model is typically where we would find interfaces that provide object saving and retrieving behavior, called ...


Only top voted, non community-wiki answers of a minimum length are eligible