I would like to ask more experienced users if passing IPrincipal interface to domain layer is a good practice or not. My opinion is that it should stay only in application layer. Am I wrong about this? Thanks for answers.
The IPrincipal has a meaning for the domain? I think not. This is a .net interface, basically an implemenation detail. However your domain might make use of the concept of a member or user and you could use IPrincipal as the implementation, although I don't think the domain would need exactly the behaviour of IPrincipal.
So my answer is don't pass it unless the domain really needs it at such.
Related
I am new to DDD and this is the first project for me to apply DDD and clean architecture,
I have implemented some code in the domain layer and in the application layer but currently, I have a confusion
now I have an API which is placeOrder
and to place the order I need to grab data from other microservices, so I need to grab production details from product service and address details from user profile microservice
my question is, should these data are pulled into the domain layer or in the application layer?
is it possible to implement a domain service that has some interfaces that represent the product service API and use that interface in the domain layer and it will be injected later using dependency injection or should I implement the calling of this remote API in the application layer?
please note that, calling product service and address service are prior steps to create the order
Design is what we do when we want to get more of what we want than we would get by just doing it. -- Ruth Malan
should these data are pulled into the domain layer or in the application layer?
Eric Evans, introducing chapter four of the original DDD book, wrote
We need to decouple the domain objects from other functions of the system, so we can avoid confusing the domain concepts with other concepts related only to software technology or losing sight of the domain altogether in the mass of the system.
The domain model doesn't particularly care whether the information it is processing comes from a remote microservice or a cache. It certainly isn't interested in things like network failures and re-try strategies.
Thus, in an idealized system, the domain model would only be concerned with the manipulation of business information, and all of the "plumbing" would be somewhere else.
Sometimes, we run into business processes where (a) some information is relatively "expensive" to acquire and (b) you don't know whether or not you need that information until you start processing the work.
In that situation, you need to start making some choices: does the domain code return a signal to the application code to announce that it needs more information, or do we instead pass to the domain code the capability to get the information for itself?
Offering the retrieve capability to the domain code, behind the facade of a "domain service" is a common implementation of the latter approach. It works fine when your failure modes are trivial (queries never fail; or abort-on-failure is an acceptable policy).
You are certainly going to be passing an implementation of that domain service to the domain model; whether you pass it as a method argument or as a constructor argument really depends on the overall design. I wouldn't normally expect to see a domain entity with a domain service property, but a "use case" that manipulates entities might have one.
That all said, do keep in mind that nobody is handing out prizes for separating domain and application code in your designs. "Doing it according to the book" is only a win if that helps us to be more cost effective in delivering solutions with business value.
In your online documentation regarding domain services ("https://aspnetboilerplate.com/Pages/Documents/Domain-Services") you have section called "How do we force to use of the Domain Service?"
In there you imply that there is a lot of external documentation around the concept of injecting a kind of "policy" service into the entity as a way to do this, but the artice is kind of vague on the implementation of that class, along with where it should be injected and how it is used. I have been scouring the Internet for examples of this kind of design to force the use of domain services, but haven't been able to find anything.
Just browsing that documentation leaves too many questions..
Additionally, I was hoping I could find a simple implementation of an Abp that provided an example of this, but could not find anything.
I'm very curious about this because I have found it to be a big problem with large projects in the past: developers writing their own code in the application service layer, not knowing that the capabilities were already provided in some domain driven "Manager" service.
Can you provide a quick small sample of this concept fully implemented? Using Abp would be great, but a generic example would be fine as well.
take care,
jasen
A few thoughts:
The Policy pattern in that code plays no role in forcing use of the domain service. It is only making task assignment more modular and more SRP compliant.
There's only so much defensive programming can do for you. Sure, making AssignedPersonId protected so that it cannot be directly assigned is a good thing, but a programmer could just as well change it back to public. Don't rely too much on technical code to prevent bad developer behavior - shared practices and team culture are much more efficient.
Questioning application sample or template code (as you do) is sound. Don't take that code as gospel truth - it was never meant to be exemplary in the first place. Try your own stuff and learn from your mistakes. Experience is not something that can be transmitted through such a document.
Since the most similar questions are related to ASP MVC I want to know some common right choice strategies.
Lets try to decide, will it go into the business layer or sit on the service layer.
Considering service layer to have a classical remote facade interface it seems to be essential just to land permission checks here as the user object instance is always here (the service session is bound to the user) and ready for .hasPermission(...) calls. But that looks like a business logic leak.
In the different approach with an implementation of security checks in the business layer we pollute domain object interfaces with 'security token' arguments and similar things.
Any suggestions how to overcome this tradeoff or maybe you know the only true solution?
I think the answer to this question is complex and worth a bit of thought early on. Here are some guidelines.
The service layer is a good place for:
Is a page public or only open to registered users?
Does this page require a user of a specific role?
Authentication process including converting tokens to an internal representation of users.
Network checks such as IP and spam filters.
The business layer is a good place for:
Does this particular user have access to the requested record? For example, a user should have access to their profile but not someone else's profile.
Auditing of requests. The business layer is in the best situation to describe the specifics about requests because protocol and other details have been filtered out by this point. You can audit in terms of the business entities that you are setting policy on.
You can play around a bit separating the access decision from the enforcement point. For example, your business logic can have code to determine if a user can access a specific role and present that as a callback to the service layer. Sometimes this will make sense.
Some thoughts to keep in mind:
The more you can push security into a framework, the better. You are asking for a bug (and maybe a vulnerability) if you have dozens of service calls where each one needs to perform security checks in the beginning of the code. If you have a framework, use it.
Some security is best nearest the network. For example, if you wish to ban IP addresses that are spamming you, that definitely shouldn't be in the business layer. The nearer to the network connection you can get the better.
Duplicating security checks is not a problem (unless it's a performance problem). It is often the case that the earlier in the workflow that you can detect a security problem, the better the user experience. That said, you want to protect business operations as close to the implementation as possible to avoid back doors that bypass earlier security checks. This frequently leads to having early checks for the sake of UI but the definitive checks happening late in the business process.
Hope this helps.
I'm looking at developing a system (primarily web based) that has a clearly defined domain.
Parts of the domain include entities like Diary, Booking, Customer, etc.
However I created another entity called User whose intention is for authentication and authorization only (it seemed wrong to contaminate the Customer entity with data specific to authentication). I figure this isn't part of the domain of "making bookings", but specifically this should belong to the application layer (I'm trialling a hexagonal architecture).
I'm accessing my repositories using interfaces in my domain model and wiring them up to my persistence layer using IoC.
My questions are this:
Should I put the authentication/authorization code in the application
and keep it out of the domain?
If I do keep it out of the domain, should I put the interface for the
UserRepository in the application layer also (I think this would
make sense)?
If I do keep it out of the domain, I will end up with entities also in the application layer called User etc. This seems wrong.
What are people's thoughts?
[EDIT]
I've gone for a solution that takes a bit from both answers, so thanks for answering and I've +1'd you both.
What I've done is put the authentication/authorisation code in a subdomain (secondary adapter), in a separate project, and because it requires access to it's own persistence (a few collections in a separate RavenDB database), I'm including these straight into the separate project keeping them separate from the main persistence layer.
Should I put the authentication/authorization code in the application
and keep it out of the domain?
No, you should keep authentication/authorization code out of the core domain. It belongs to a generic subdomain.
If I do keep it out of the domain, should I put the interface for the
UserRepository in the application layer also (I think this would make
sense)?
You could keep UserRepository in the domain layer, but you'd better keep the "access and identify" subdomain and the "making bookings" core domain separated with each other. You could use different packages or namespace.
The next challenge is how to integrate these two domains. In my humble opinion, you may:
Expose a DomainService from "access and identify" subdomain to the application layer for making authentication/authorization decisions.
Sometimes we have to find out who made Diaries and Bookings, in this case, use the identifier of the User is enough. Other information such as "favorite tags" or something like that is usually not needed in "making booking" core domain.
Authentication is a generic domain, not a part of your domain. So, yes, keep it in some component in application layer.
Not all parts of your system should follow DDD patterns. You can use UserRepository if you see a benefit for this but I would use just some already available component/popular library of your environment like MembershipProvider in ASP.NET world.
I'm modeling my first DDD application and I caught stuck with this doubt...
In my application and infrastucture layers I have some details that need to be persisted, but, since these are not domain specific, I don't like to name it repositories. Someone can help me figure out how to name it?
Thanks.
DDD and the Repository pattern (RP) are different things, it just happens that DDD makes use of RP. This means that you can wrap everything related to persistence in repositories, they just won't be Domain Repositories. Probably in your case you'd have PaymentGatewaysRepository or smth like that.
Point is, if you wrap persistence access details into a class so that the rest of the app doesn't care about storage, you're using the repository pattern no matter how you'll name that class.
You should elaborate some more... Why isn't it modeled? Is it only configuration settings, things outside of the scope of the model? Like logs, etc? Some names come to mind: Serialization, configuration, settings, etc.
Considering your comment, configuration settings are really orthogonal to a Domain Model, but payment gateway settings may or may not be outside of the model. Id depends on the kind of application you are writing. I believe that if you are writing a payment processor, then it is a bona fide "member of your" domain model :-) You can also model generic configurations in the model... imagine that your users will have their own overriden settings.. The config "model" could weakly reference the domain model...
You can also model these specifics in another domain entirely... a reusable domain model with its own persistence, and which could be used in different domains as an add-on...