DDD: Where to put logic in aggregation root - oop

Still experimenting with DDD and have some doubts, maybe someone would help me.
Lets say that I have 2 models:
public class Event
{
User Creator;
List<User> Members;
}
public class User {}
My problem is that I cannot see place for logic that I want to implement. I need 3 actions:
User join event
User leave event
Creator remove user from event (only Creator can remove users)
For now I just created domain service EventUserService that calls Event.RemoveUser/AddUser and ie. checks if CurrentUser (provided by UserService) is creator of event (have rights to remove other users).
Maybe that approach is ok, but I still feel that I should putt that logic into aggregation roots, ie. :
User.JoinEvent(Event) - i can add passed Event to User.Events collection (bidirectionall) base on some logic.
User.LeaveEvent(Event) - analogous to JoinEvent.
User.RemoveUserFromEvent(User,Event) - I can have CreatedEvents collection in User and for Event from that collection I can call Event.RemoveUser(User) - this way I will make sure that only creator can kick someone.
Or
Evet.RemoveUser(UserToRemove) - but how I will make sure that its called by creator ?
If first two method looks ok (at least for me), 3rd one would create Event.RemoveUser (to manage Event members collection) method that could be used to bypass logic residing in User.RemoveUserFromEvent.
So, in the end I have 2 questions:
What is your approach in situation like this where two aggregation roots works together and one operation is determine by logic residing in both of them? Maybe some kind of methoods like User.CanJoinEvent(Event) ?
What about creating "danger" point like User.RemoveUserFromEvent
Maybe someone can putt a little bit light on that for me, every help would be nice.

public class Event
{
User Creator;
List<User> Members;
}
Don't do that. You are breaking Law Of Demeter and the Event class has no control over the changes in Members or the users in that list. You should instead define methods in the Event class which is used to handle the members.
Now, if you do that change, i.e. have something like this:
public class Event
{
User Creator { get private set; }
bool IsMember(string name);
void AddMember(User user);
}
You'll suddenly have solid places to generate the events.
but how I will make sure that its called by creator ?
In .NET you can use Thread.CurrentPrinicpal to get information about the logged in user. It do however require that you implement your own IPrincipal/IIdentity.
Remember: You should ALWAYS make sure that the models are in a valid state in DDD. That usually means that all setters should be private: http://blog.gauffin.org/2012/06/protect-your-data/

Related

Does DDD violate some OOP principles?

Perhaps I might be confused or misunderstanding some basic principles. When applying DDD in an Axon based event sourcing project, you define a number of aggregates each of them having several command handler methods verifying if a state change of the aggregate is valid and a corresponding collection of event handler methods applyling each requested state change.
EDIT START:
So an aggregate could look like
#Aggregate
public class Customer {
#AggregateIdentifier
private CustomerId customerId;
private Name name;
#CommandHandler
private Customer(CreateCustomerCommand command) {
AggregateLifecycle.apply(new CustomerCreatedEvent(
command.getCustomerId(), command.getName());
}
#EventSourcingHandler
private void handleEvent(CustomerCreatedEvent event) {
this.customerId = event.getCustomerId();
this.name = event.getName();
}
}
EDIT END
So my first question is: Am I correct to conclude the aggregate does not implement any state changing methods directly (typical public methods altering the properties of the aggregate instance) but all state changing methods are defined in a separate domain service interacting with Axon's command gateway?
EDIT START:
In other words, should an aggregate define setters responsible for sending a command to the framework which will result in the corresponding command handler and event handler being called by adding the code below to the aggregate?
public void setName(String name){
commandGateway.send(new UpdateNameCommand(this.customerId, name));
}
#CommandHandler
private void handleCommand(UpdateNameCommand command) {
AggregateLifecycle.apply(new NameUpdatedEvent(command.getCustomerId(), command.getName());
}
#EventSourcingHandler
private void handleEvent(NameUpdatedEvent event) {
this.name = event.getName();
}
This seems to violate some recommendations since a reference to the gateway is needed from within the aggregate.
Or do you typically define such methods in a separate service class which will then send the command to the framework.
#Service
public class CustomerService {
#Autowired
private CommandGateway gateway;
public void createCustomer(String name) {
CreateCustomerCommand command = new CreateCustomerCommand(name);
gateway.send(command);
}
public void changeName(CustomerId customerId, String name) {
UpdateNameCommand command = new UpdateNameCommand (customerId, name);
gateway.send(command);
}
}
This seems the correct approach to me. This seems to make (at least to my opinion) the aggregate's behavior not directly accessible for the outer world (all command and event handler methods can be made private) like a more "traditional" objects which are the entry-point for requesting state changes...
EDIT END
And secondly: Isn't this in contradiction with OOP principles of each class defining its (public) interface methods to interact with? In other words, doesn't this approach make an object a more or less dump object in which direct interaction is impossible?
Thanks for your feedback,
Kurt
So my first question is: Am I correct to conclude the aggregate does not implement any state changing methods directly (typical public methods altering the properties of the aggregate instance) but all state changing methods are defined in a separate domain service interacting with Axon's command gateway?
Absolutely not! The aggregate itself is responsible for any state changes.
Probably, the misconception is around the Command Handler (method) within the aggregate, when using event sourcing. In that case, the Command Handler (method) should not directly apply changes. Instead, it should apply an Event, which then invokes an Event Sourcing Handler (method) within that same aggregate instance to apply the state changes.
Whether using Event Sourcing or not, the aggregate should expose actions (e.g. Command Handlers) only, and make its decisions based on those actions. Preferably, the Aggregate (of a Command Handler) doesn't expose any state outside of the Aggregate boundaries.
And secondly: Isn't this in contradiction with OOP principles of each class defining its (public) interface methods to interact with? In other words, doesn't this approach make an object a more or less dump object in which direct interaction is impossible?
That would have been the case if the aggregate relied on external components to manage its state. But it doesn't.
additional reactions after question edit
So my first question is: Am I correct to conclude the aggregate does not implement any state-changing methods directly (typical public methods altering the properties of the aggregate instance) but all state changing methods are defined in a separate domain service interacting with Axon's command gateway?
I think it's exactly the opposite. The first aggregate in the question is an example of an aggregate that has all state changing operations inside of itself. Exposing setters to "change state" is a very bad idea. It forces the logic to decide on when to change this value outside of the Aggregate. That, in my opinion, is a "violation" of OOP.
Aggregates, in a DDD and/or CQRS context should no be instructed to change state. Instead, they should receive the actual business intent to react to. That is what a Command should reflect: the business intent. As a result, the Aggregate may change some attributes, but only to ensure that any commands happening after that behave in such a way that it reflects the things that have happened before. With event sourced aggregates, that has an extra intermediate step: applying an event. That needs to be done to ensure that sourcing an aggregate from past decisions yields the exact same state. Also note that these events are not "state change decisions", but "business decisions". The state changes are a result of that.
Final comments
The service class shown in the end would be the typical interaction. A component sending commands, not directly interacting with the Aggregate instance. However, the "UpdateNameCommand" as a comparison with the "setName" in the previous example put me off, since Commands should not be "C(R)UD" operations, but actual business operations. At may be the case that UpdateName is such a business operation.

How to properly do resource-based authorization in ASP.NET Core 2.2?

I have an ASP.NET Core 2.2 application where I am displaying some documents. Most documents are public, so anonymous access is fine. However, some documents are private (i.e. they require authentication/authorization), and in the future some documents might also require a valid subscription. All documents are retrieved using the same actions, so we only know the required permissions after the documents have been loaded. We also load some resources as static files (IApplicationBuilder.UseStaticFiles), but I guess that shouldn't really be an issue as StaticFileOptions.OnPrepareResponse can be used for custom authorization code.
The logic for who gets access to private documents is currently really simple. And at the moment, we only display documents, we don't allow any other kind of operation on them (editing, deletion etc.). To me, this sounds like a pretty standard case of resource-based authorization.
Anyway, I have found this article and from what I've understood, I need to define a policy (identified by a magic string - what's up with that?!) as well as a requirement and an AuthorizationHandler<MyRequirement, MyResource> which will perform the actual authorization logic. Then, inside my controller action, I will need to call IAuthorizationService.AuthorizeAsync and pass in the user, the resource and the policy name (the magic string) and, based on the result from that method, allow or deny access. That seems more than convoluted for what I'm trying to accomplish. It would probably be easier if I simply defined my own kind of "authorization service" and simply dropped the whole policy and requirement stuff. I also think it's less than ideal that I would have to replicate the if-else logic in all affected controller actions.
Surely I'm not the only one with this issue. Is there something I've missed?
If there are indeed good reasons for using policies and requirements, how would you name them in a case like this? I'm really feeling a little lost.
Maybe it would make sense to use the type of document (public, private, subscribers-only) as the policy name?
In the end, we didn't want to deal with this stuff and just wrote our own AuthorizationService, which is injected into the controller like any other service.
It loads the required permissions for all documents the first time it is used and caches them.
Our controller methods then look something like this:
[HttpGet("[action]")]
public async Task<Document> GetDocument(string documentId)
{
if (_authorizationService.MayAccess(User, documentId))
{
return _documentRepository.GetDocument(documentId);
}
else
{
Response.StatusCode = StatusCodes.Status403Forbidden;
return null;
}
}
I recommend the last approach explained in this article - https://www.red-gate.com/simple-talk/dotnet/c-programming/policy-based-authorization-in-asp-net-core-a-deep-dive/
Allows you to keep you controller clean, by just applying annotation with the name of the policy. In the handler you must implement the logic checking if person can access the resource - it can be based for example on checking a property ownerId in a resource(for example in database table column) or a member of a certain group in AD, or anything else.
EDIT:
Using Requirements and RequirementsHandlers - I have done something similiar.
I don't know how should your logic exactly work, so I am just going to assume some.
lets say you have a get endpoint: documents/documentId
You want to apply logic which will make this document accessible only to the document owner. Obviously, you need somewhere to store who is the owner of the document, so lets keep that in property of a document entity.
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, IsDocumentOwner requirement, DocumentRepository documentRepository)
{
if (context.Resource is AuthorizationFilterContext ctx)
{
var documentId = ctx.RouteData.Values["documentId"]?.ToString();
//here load document from repo and check if the property ownerId is equal to current user id
var userId = context.User.Claims.FirstOrDefault(x => x.ToString().Contains(oid))?.Value;
//if yes, make the request pass to the body of a controller with the attribute
context.Succeed(requirement);
}
}
implement IsDocumentOwner:
public class IsDocumentOwner : IAuthorizationRequirement
{
}
in your Startup.cs add:
services.AddAuthorization(options =>
{
options.AddPolicy(
nameof(IsDocumentOwner),
policyBuilder => policyBuilder.AddRequirements(
new IsDocumentOwner()));
});
then, last step, apply attribute on your controller method
[Authorize(Policy = "IsDocumentOwner")]
[HttpGet("{documentId}")]
public YourDocumentObjectResultClass GetDocument([FromRoute]string documentId)
{
//stuff you do when current user is owner of the document, probably just display the doc
}
To your IsDocumentOwner handler you can inject any service by constructor(visualised by repository above), for example, to check if the user is a member of a group on azure ad

Is user class responsible for authentication?

I have class named User, it has fields like username, password, firstName... . is it good to place authenticate(username, password) method in it?
Ideally no, that should be the job of the controller. User class should be just a data class, which is used by the controller (the business logic class) to evaluate things like Authenticate etc.
Explanation:
You need to modularize your code(break it into components) and each component should be an independent entity but requires other components to give the whole picture of the system.
It appears by your question that you want to perform some business layer operation in your DO(data object) class. It can be done but is never recommended as it kills the idea of separation of concerns.
As for controllers, you could do something like
Have object/entity level managers, i.e, for every entity you have a manager to handle its business logic stuff. Say for a User class you have a UserManager.
Have conceptual level controllers. This means that you have controllers that handle a specific module of your system(an entire concept). For example, if you have a website that needs to authenticate users, you can have an AuthenticationController.
Now, Authentication must not necessarily map to just one table/object, though it appears that its sole target is(logically) your User table/class etc, it could be doing other stuff and accessing other entities(depending on the requirement) etc. So by having entity level managers that are used by conceptual level controllers, you could ease your development.
I would say no. Better is to have a Connection and create a user using login method with username and password:
class Connection{
public:
Connection(string connectionString);
User login(string userName, string Password);
};
That would break the MVC (Model View Controller) structure. It is best to keep these three separated for code elegance, readability, and maintainability. A quick example would be, in Java:
Model:
public class User {
private String username;
private String password;
(...)
}
Controller:
import yourmodelpackage;
public class MyController {
public static boolean authenticate(String username, String password) {
//your logic
}
}
View:
//call your authenticate() method through the controller
MyController control = new MyController();
boolean b = control.authenticate(username, password);
There are a few design patterns that maximize the use of inheritance for this structure. I'd recommend looking into the Decorator Design Pattern.
You could have a method hasPassword(string password) on the User class, if you absolutely wanted to encapsulate the verification in that class.

Advice on how I should return more than a simple type from my service layer

In my mvc3 application, I have things setup like:
1. repositories for each entity
2. service class for each entity that wraps the bare nhibernate db calls with business logic
Now for example, a class that registers a user, I want the service class to return something more than a boolean or user object if the user can register successfully.
Is this good practise?
Reason being, a person may fail to register correctly for reasons like:
1. duplicate email address in the system
2. duplicate username
3. etc.
So my method may look like:
public User Register(User newUser)
{
// check for a user with the same email
// check for a user with the same username
// validation checks etc.
return user;
}
I am thinking of creating a UserRegistrationResponse object so I can return back a much richer return value.
So something like:
public UserRegistrationResponse Register(User user)
{
..
return userRegistrationResponse;
}
This way I can return back a user frienly response I can propogate to the UI layer, and still get the user object and other information etc.
Comments on this approach?
I guess the only other way would be to throw exceptions, but is that really a good idea? The idea is for me to able to re-use these service classes, like say in a Restful service layer I will need in the future.
This is very common. 10 out of 10 WCF projects I've worked on in the past 3 years used this pattern. This includes legacy projects at three different companies, green field development and mvc/webforms projects.

Does dependency injection increase my risk of doing something foolish?

I'm trying to embrace widespread dependency injection/IoC. As I read more and more about the benefits I can certainly appreciate them, however I am concerned that in some cases that embracing the dependency injection pattern might lead me to create flexibility at the expense of being able to limit risk by encapsulating controls on what the system is capable of doing and what mistakes I or another programmer on the project are capable of making. I suspect I'm missing something in the pattern that addresses my concerns and am hoping someone can point it out.
Here's a simplified example of what concerns me. Suppose I have a method NotifyAdmins on a Notification class and that I use this method to distribute very sensitive information to users that have been defined as administrators in the application. The information might be distributed by fax, email, IM, etc. based on user-defined settings. This method needs to retrieve a list of administrators. Historically, I would encapsulate building the set of administrators in the method with a call to an AdminSet class, or a call to a UserSet class that asks for a set of user objects that are administrators, or even via direct call(s) to the database. Then, I can call the method Notification.NotifyAdmins without fear of accidentally sending sensitive information to non-administrators.
I believe dependency injection calls for me to take an admin list as a parameter (in one form or another). This does facilitate testing, however, what's to prevent me from making a foolish mistake in calling code and passing in a set of NonAdmins? If I don't inject the set, I can only accidentally email the wrong people with mistakes in one or two fixed places. If I do inject the set aren't I exposed to making this mistake everywhere I call the method and inject the set of administrators? Am I doing something wrong? Are there facilities in the IoC frameworks that allow you to specify these kinds of constraints but still use dependency injection?
Thanks.
You need to reverse your thinking.
If you have a service/class that is supposed to mail out private information to admins only, instead of passing a list of admins to this service, instead you pass another service from which the class can retrieve the list of admins.
Yes, you still have the possibility of making a mistake, but this code:
AdminProvider provider = new AdminProvider();
Notification notify = new Notification(provider);
notify.Execute();
is harder to get wrong than this:
String[] admins = new String[] { "joenormal#hotmail.com" };
Notification notify = new Notification(admins);
notify.Execute();
In the first case, the methods and classes involved would clearly be named in such a way that it would be easy to spot a mistake.
Internally in your Execute method, the code might look like this:
List<String> admins = _AdminProvider.GetAdmins();
...
If, for some reason, the code looks like this:
List<String> admins = _AdminProvider.GetAllUserEmails();
then you have a problem, but that should be easy to spot.
No, dependency injection does not require you to pass the admin list as a parameter. I think you are slightly misunderstanding it. However, in your example, it would involve you injecting the AdminSet instance that your Notification class uses to build its admin list. This would then enable you to mock out this object to test the Notification class in isolation.
Dependencies are generally injected at the time a class is instantiated, using one of these methods: constructor injection (passing dependent class instances in the class's constructor), property injecion (setting the dependent class instances as properties) or something else (e.g. making all injectable objects implement a particular interface that allows the IOC container to call a single method that injects its dependencies. They are not generally injected into each method call as you suggest.
Other good answers have already been given, but I'd like to add this:
You can be both open for extensibility (following the Open/Closed Principle) and still protect sensitive assets. One good way is by using the Specification pattern.
In this case, you could pass in a completely arbitrary list of users, but then filter those users by an AdminSpecification so that only Administrators recieve the notification.
Perhaps your Notification class would have an API similar to this:
public class Notification
{
private readonly string message;
public Notification(string message)
{
this.message = message;
this.AdminSpecification = new AdminSpecification();
}
public ISpecification AdminSpecification { get; set; }
public void SendTo(IEnumerable users)
{
foreach(var u in users.Where(this.AdminSpecification.IsSatisfiedBy))
{
this.Notify(u);
}
}
// more members
}
You can still override the filtering behavior for testing-purposes by assigning a differet Specification, but the default value is secure, so you would be less likely to make mistakes with this API.
For even better protection, you could wrap this whole implementation behind a Facade interface.