Placement of service methods - oop

Let's assume I have two service classes with the following methods:
GroupService
createGroup()
deleteGroup()
updateGroup()
findGroup()
UserService
createUser()
deleteUser()
updateUser()
findUser()
Now, I am thinking about the aesthetics of theses classes.
Imagine we want to implement a method which search for all user of a specific group.
Which service class is responsible for such a method?
I mean, the return value is a user (or maybe a collection of users) but the parameter (which means the name of the group) is a group.
So which service class is the better place to put this method in?

None of both. The method belongs in the class Group, which is returned by createGroup() and findGroup(). If only these two services are your options, though, go with the GroupService, because all arguments of GroupService get group names as arguments. It is more usual to vary the return type of methods than the argument.

I'd suggest the User Service, since you are requesting User entities. A service should shield consumers from implementation details (persistence mechanism etc), if the users were returned from the Group Service, it would require knowledge of how users are persisted.

I would create another class called "Membership" and have the methods that search for users in groups or groups a particular user belongs to. I tend to err on the side of large number of small classes rather than small number of large classes.

Depends on the way of your thinking, If you want to search on users with specific group, So in fact you want do some search on users with specific criteria, so It's better to put it in user service, but if you want to get some property from group, it's better to put it in group service, You should show what's your class signature and their responsibility.

Related

What is the difference between using user.Email vs await _userManager.GetEmailAsync(user)?

What is the difference between using user.Email vs await _userManager.GetEmailAsync(user)?
I mean, once I have the user instance itself, what is the use of the _userManager's GetEmailAsync() method which takes exactly that user instance as parameter? I can access the user's email via its property.
I examined the source and I do understand that there is an abstraction layer of using IUserEmailStore but its default implementation is just returning the Email property...
I also do understand, that may exist other implementations, of IUserEmailStore but this case the question will arise: are the user.Email property and _userManager.GetEmailAsync(user) consistent to each other, or are not?
If not, that is a problem, if yes, then we are returned to the original question: what is the use case of using _userManager.GetEmailAsync(user)?
(the same question goes to UserName, PhoneNumber, etc properties)
What is the difference between using user.Email vs await UserManager.GetEmailAsync(user)?
user.Email only works if your TUser actually has an Email property in the first place.
Fun-fact: ASP.NET-Core-Identity does not actually require whatever class you're using for your TUser to have a String Email property.
i.e. what you're presupposing (that users have e-mail addresses) is not actually guaranteed in, nor required by, ASP.NET-Core-Identity.
ASP.NET-Core-Identity's only constraint on TUser is TUser : class, so you could even use String or IDictionary for your TUser if you're brave enough.
While ASP.NET-Core-Identity does have a String Email { get; } property defined only on class Microsoft.AspNetCore.Identity.IdentityUser<TKey>, but you are not obligated to use this class at all: it's just a prewritten implemention that covers the most common use-cases and (probably) saves most people time by having them subclass it.
But there are also other scenarios to consider:
...such as domain-model design where users have multiple e-mail addresses per user, in which case having a single scalar String Email { get; } property simply won't work... though neither would GetEmailAsync either, but that's another part of ASP.NET-Core-Identity's design that you missed: you can implement IUserStore<TUser> and not implement IUserEmailStore<TUser>, so there wouldn't be either an Email property nor a GetEmailAsync method. (Just make sure you don't subclass class UserStoreBase) and instead build your store implementation from scratch.
In this hypothetical case, where no types implement IUserEmailStore<TUser>, there wouldn't be any methods anywhere in your codebase that would have to throw NotImplementedException or NotSupportedException. And that's a good thing: a common mantra when designing a domain-model is to "make invalid things impossible" (that's my corruption of the original maxim "make invalid state unrepresentable").
Another scenario is some (atypical, I'll admit) system where Users do have an email address, but it's not stored or represented by the in-memory User object, in which case you would have to use a custom implementation of GetEmailAsync to get a user's email address every time.
I imagine this might be a possibility when using a back-end user-store with extremely fine-grained security (e.g. some paranoid Active Directory setup where the current Thread's NT security token is used to attest permission to request e-mail addresses from the directory... but that idea is just speculation and I hope no-one ever actually has to support that, at least not without good blood-pressure medication on-hand).
In conclusion: Not every system has user e-mail addresses, and ASP.NET Core Identity doesn't require them to expose them - and the (admittingly very complicated) design of ASP.NET Core Identity reflects that.

What is naming convention for DTOs in a webservice

I'm designing a restful web service and I was wondering what should I name my DTOs. Can I use suffixes like Request and Response for them? for example for addUser service, there will be 2 DTOs named: AddUserRequest and AddUserResponse.
Does your organization already have a schema that describes a canonical user that you pass in? If that's what you're using, of course you would use the name from that schema. Otherwise, describe them just as you would any class or schema element.
Note that since a DTO doesn't contain its own methods, you probably would not give it a name with an action verb.
However, consider calling them AddUserRequest and AddUserResponse, especially if the method requires more info than just your regular user DTO. This fits with the Interface Segregation Principle in that your interface parameters should be specifically tailored to the request itself (it shouldn't require elements that are unrelated to the request; and you shouldn't have function-type parameters that change the request, those should be extracted into their own calls.) The AddUserRequest might then contain an element called User that holds the user-specific data, and another element holding the set of other associated data on the request, perhaps groups or access permissions, that sort of thing.
DTOs (Data Transfer Object) are like POJOs(Plain Old Java Objects). It should only have getters and setters and not any business logic.
From Wikepedia:
A data transfer object is an object that carries data between
processes. The motivation for its use is that communication between
processes is usually done resorting to remote interfaces (e.g., web
services), where each call is an expensive operation. Because the
majority of the cost of each call is related to the round-trip time
between the client and the server, one way of reducing the number of
calls is to use an object (the DTO) that aggregates the data that
would have been transferred by the several calls, but that is served
by one call only.
The difference between data transfer objects and business objects or
data access objects is that a DTO does not have any behavior except
for storage and retrieval of its own data (mutators and accessors).
DTOs are simple objects that should not contain any business logic
that would require testing.
This pattern is often incorrectly used outside of remote interfaces.
This has triggered a response from its author[3] where he reiterates
that the whole purpose of DTOs is to shift data in expensive remote
calls.
So ideally for those actions you should create some helpers or you can add those as controllers.
Since it is a RESTful service, ideally the user addition/creation request should send back 201 created HTTP status code , with userId in location header and no response body. For the request, you could name it like UserDetails or UserData or simply User. Refer https://pontus.ullgren.com/view/Return_Location_header_after_resource_creation

How to update shared information between 2 representations of the same entity in different contexts?

This question is related, but more specific than this question.
I'm going to use a simple example here. Say we have a User entity in one context and a Customer entity in another context. These are 2 different representations of the same entity.
Let's say the User and Customer both have an email address, but the email address is always changed via the bounded context that the User belongs to. So the user context is the source of truth for the email address. So ideally I would like the email address in the Customer context to be immutable from the point of view of the customer context.
So when the email address is changed in the user context, an EmailAddressChanged event is emitted. This is fine; I subscribe to the event in the Customer context. However, I now need to handle this event by mutating the Customer email address. So I need some sort of command method to make this change.
How can I ensure that the command method is not used, other than when handling the event from the User context?
If I allow mutation in both contexts then they both become sources of truth and I need double the number of events and handlers to ensure that the information remains consistent in both contexts
Maybe there is a hidden customer/supplier relationship between these bounded contexts? If User bc is the source of truth for Customer bc, then User bc might expose an API to be accessed by downstream contexts (Customer, maybe something more?). In your question you said only the email address should be "immutable" and dependent on User context - however, I think it might a hint that entire Customer context is a consumer/customer of User context and should use its public API (which should not expose internal user domain model directly - some facade classes are required to hide the details).
If that's not the case, and there is no such relationship between the contexts - you can use a specialized component in your Customer bc to make changes to the database, without directly invoking domain methods. Then, the repository can be used to query customers and recreate them with updated email address. My point is - if you want customer bc to apply EmailAddressChanged events, you obviously need something to alter the database, but you don't need to do that via domain methods. The component applying EmailAddressChanged events would be part of the infrastructure layer of Customer context. If you use this solution, then there is no risk of modifying customers via business case scenarios.
Btw, isn't your Customer in fact a specialized read model of User context?

Avoiding abstract classes and inheritance

consider I am having an Event with Invitations (each "invited person" represents an Invitation, so multiple Invitations are out for a single Event):
[«aggregate root»;Invitation]<>1..*-[«value object»;EventIdentifier]
[«value object»;EventIdentifier]-<>[«aggregate root»;Event]
[«value object»;Invitee|emailAddress;facebookIdentifier]-<>[«aggregate root»;Invitation]
The Invitee, however, can bei either an Email Address or a facebookIdentifier, that's the nature of the business logic.
Usually I would have made an AbstractInvitee with FacebookInvitee and EmailInvitee, and created an association to the abstract, but that's evil as I know now.
Should I, instead, have actually FacebookInvitee and EmailInvitee and the Invitation has each a facebookInvitee and an emailInvitee property; and a Service or so would merge them together, if necessary?
Thanks for your advice!
Edit
I just came to the following idea which looks rather neat,
[«value object»;Invitee|type;identifier]-<>[«aggregate root»;Invitation]
The type is somehow a constant with FACEBOOK and EMAIL, and the identifier then is the FB UID or the email address respectively.
Usually I would have made an AbstractInvitee with FacebookInvitee and
EmailInvitee, and created an association to the abstract, but that's
evil as I know now.
Inheritance is not that evil.
If your classes FacebookInvitee and EmailInvitee have the same interface I see no reason to avoid inheritance. Inheritance adds complexity if interfaces are different and casting to concrete types is needed.
The type is somehow a constant with FACEBOOK and EMAIL, and the
identifier then is the FB UID or the email address respectively.
Your example is very similar to Replace Subclass with Fields refactoring. Anyway it will be needed to write if-else code-block to check invitee type and use its identifier for sending an invitation somewhere. Who should be responsible for it? In your solution Invitee is simply a DTO without behaviour. If Invitee has behaviour and can Send() an invitation itself then I would use inheritance and implement Send() for every concrete class (e.g. FacebookInvitee, EmailInvitee).
I'd still keep an abstract Invitee value object with 2 derivatives EmailInvitee and FacebookInvitee.
Each type of Invitee can raise its own flavor of WasNotified Domain Event which is then captured by an Infrastructure layer notification service that knows how to handle it.
I like your idea in edit.
You could place a NotificationService in the domain layer and add adapters in the infrastructure layer(FacebookNotificationService / EmailNotificationService).
And a NotificationDispatcher(it is also an adapter but aggregates other adapters) to dispatch notification(by invitee type) to the corresponding adapter.

MVVM on top of claims aware web services

I'm looking for some input for a challenge that I'm currently facing.
I have built a custom WIF STS which I use to identify users who want to call some WCF services that my system offers. The WCF services use a custom authorization manager that determines whether or not the caller has the required claims to invoke a given service.
Now, I'm building a WPF app. on top of those WCF services. I'm using the MVVM pattern, such that the View Model invokes the protected WCF services (which implement the Model). The challenge that I'm facing is that I do not know whether or not the current user can succesfully invoke the web service methods without actually invoking them. Basically, what I want to achieve is to enable/disable certain parts of the UI based on the ability to succesfully invoke a method.
The best solution that I have come up with thus far is to create a service, which based on the same business logic as the custom authorization policy manager will be able to determine whether or not a user can invoke a given method. Now, the method would have to passed to this service as a string, or actually two strings, ServiceAddress and Method (Action), and based on that input, the service would be able to determine if the current user has the required claims to access the method. Obviously, for this to work, this service would itself have to require a issued token from the same STS, and with the same claims, in order to do its job.
Have any of you done something similar in the past, or do you have any good ideas on how to do this?
Thanks in advance,
Klaus
This depends a bit on what claims you're requiring in your services.
If your services require the same set of claims, I would recommend making a service that does nothing but checks the claims, and call that in advance. This would let you "pre-authorize" the user, in turn enabling/disabling the appropriate portions of the UI. When it comes time to call your actual services, the user can just call them at will, and you've already checked that it's safe.
If the services all require different sets of claims, and there is no easy way to verify that they will work in advance, I would just let the user call them, and handle this via normal exception handling. This is going to make life a bit trickier, though, since you'll have to let the user try (and fail) then disable.
Otherwise, you can do something like what you suggested - put in some form of catalog you can query for a specific user. In addition to just passing a address/method, it might be nicer to allow you to just pass an address, and retrieve the entire set of allowed (or disallowed, whichever is smaller) methods. This way you could reduce the round trips just for authentication.
An approach that I have taken is a class that does the inspection of a ClaimSet to guard the methods behind the service. I use attributes to decorate the methods with type, resource and right property values. Then the inspection class has a Demand method that throws an exception if the caller's ClaimSet does not contain a Claim with those property values. So before any method code executes, the claim inspection demand is called first. If the method is still executing after the demand, then the caller is good. There is also a bool function in the inspection class to answer the same question (does the caller have the appropriate claims) without throwing an exception.
I then package the inspection class so that it is deployed with clients and, as long as the client can also get the caller's ClaimSet (which I provide via a GetClaimSet method on the service) then it has everything it needs to make the same evaluations that the domain model is doing. I then use the bool method of the claim inspection class in the CanExecute method of ICommand properties in my view models to enable/disable controls and basically keep the user from getting authorization exceptions by not letting them do things that they don't have the claims for.
As far as how the client knows what claims are required for what methods, I guess I leave that up to the client developer to just know. In general on my projects this isn't a big problem because the methods have been very classic crud. So if the method is to add an Apple, then the claim required is intuitively going to be Type = Apple, Right = Add.
Not sure if this helps your situation but it has worked pretty well on some projects I have done.