Best way to encapsulate creation logic - c#

I think I have an amateur architecture question, but this is something that I've been struggling to figure out for quite a while.
I have a C# web project that creates users in several places like this:
var user = /*create user somehow*/;
_userRepository.Add(user);
_userRepository.SaveChanges();
Now I need to add logic that sends email notifications every time a user is created:
var user = /*create user somehow*/;
_userRepository.Add(user);
_userRepository.SaveChanges();
_notificationService.SendUserCreatedNotification(user);
The problem with this is I wouldn't like to add the same line of code to all the places where new user is created (DRY!).
Now, I could wrap up the Add/Save/SendUserCreatedNotification logic in a separate service:
var user = /*create user somehow*/;
_userCreationService.AddAndSave(user);
But:
the purpose of this service would be logically weird (add user to
repo, save changes to repo, send notifications); I can't even think
of a good name for this service & method
The service method would only have 3 lines of code: Add/Save/SendUserCreatedNotification
How do you usually solve such tasks? Is approach 2 the best way to go? Or maybe there exists a better approach 3?

One possible solution would be to send this notification from the _userRepository.SaveChanges(); method.
You would check your UoW change tracker for all the user entities that are in the 'Created' state and send these notifications after committing.
However, using this approach, the notification sending will be hidden in your infrastructure/data access/... layer. This means the notification sending logic will not be part of your domain/core logic. For someone to become aware of this part of the logic, they would have to dive into the implementation details of your repository (or UoW).
Instead, you could fire an event from the _userRepository.SaveChanges(); and subscribe to that event in your core logic.
The approach I would take would be the following:
In _userRepository.SaveChanges(); for every created user, fire a UserCreatedEvent event that will contain the information about the user.
Subscribe to that event in your core logic and call _notificationService.SendUserCreatedNotification(user); from the event handler.
This way, you would also decouple your user creation logic from the notification sending logic.

Related

DDD update via REST

I am new to DDD, and I am trying to figure out a way to update aggregate by using a PUT verb.
If all properties in the aggregate have private setters, then it's obvious I need to have set of functionality for every business requirement. For an example
supportTicket.Resolve();
It's clear for me that I can achieve this with an endpoint such as /api/tickets/5/resolve, but what if i want to provide a way to update whole ticket atomically?
As an example, user can make a PUT request to /api/tickets/5 with a following body
{"status" : "RESOLVED", "Title":"Some crazy title"}
Do I need to do something like this in the ApplicationSercvice
if(DTO.Status != null && dto.Status == "RESOLVED")
supportTicket.Resolve();
if(DTO.Title != null)
supportTicket.setNewTitle(DTO.title);
If that's the case and changing ticket title has some business logic to prevent changing it if the ticket is resolved, should I consider some kind of prioritizing when updating aggregate, or I am looking at this entirely wrong?
Domain Driven Design for RESTful Systems -- Jim Webber
what if i want to provide a way to update whole ticket atomically?
If you want to update the whole ticket atomically, ditch aggregates; aggregates are the wrong tool in your box if what you really want is a key value store with CRUD semantics.
Aggregates only make sense when their are business rules for the domain to enforce. Don't build a tractor when all you need is a shovel.
As an example, user can make a PUT request to /api/tickets/5
That's going to make a mess. In a CRUD implementation, replacing the current state of a resource by sending it a representation of a new state is appropriate. But that doesn't really fit for aggregates at all, because the state of the aggregate is not under the control of you, the client/publisher.
The more appropriate idiom is to publish a message onto a bus, which when handled by the domain will have the side effect of achieving the changes you want.
PUT /api/tickets/5/messages/{messageId}
NOW your application service looks at the message, and sends commands to the aggregate
if(DTO.Status != null && dto.Status == "RESOLVED")
supportTicket.Resolve();
if(DTO.Title != null)
supportTicket.setNewTitle(DTO.title);
This is OK, but in practice its much more common to make the message explicit about what is to be done.
{ "messageType" : "ResolveWithNewTitle"
, "status" : "RESOLVED"
, "Title":"Some crazy title"
}
or even...
[
{ "messageType" : "ChangeTitle"
, "Title" : "Some crazy title"
}
, { "messageType" : "ResolveTicket"
}
]
Basically, you want to give the app enough context that it can do real message validation.
let's say I had aggregates which encapsulated needed business logic, but besides that there is a new demand for atomic update functionality and I am trying to understand a best way to deal with this.
So the right way to deal with this is first to deal with it on the domain level -- sit down with your domain experts, make sure that everybody understands the requirement and how to express it in the ubiquitous language, etc.
Implement any new methods that you need in the aggregate root.
Once you have the use case correctly supported in the domain, then you can start worrying about your resources following the previous pattern - the resource just takes the incoming request, and invokes the appropriate commands.
Is changing the Title a requirement of Resolving a ticket? If not, they should not be the same action in DDD. You wouldn't want to not resolve the ticket if the new name was invalid, and you wouldn't want to not change the name if the ticket was not resolvable.
Make 2 calls to perform the 2 separate actions. This also allows for flexibility such as, the Title can be changed immediately, but perhaps "resolving" the ticket will kick off some complex and time consuming (asyncronous) work flow before the ticket is actually resolved. Perhaps it needs to have a manager sign off? You don't want the call to change "title" tied up in that mix.
If needs be, create something to orchestrate multiple commands as per #VoiceOfUnreason's comment.
Wherever possible, keep things separate, and code to use cases as opposed to minimizing interacitons with entities.
You're probably right. But it's probably wiser to encapsulate such logic inside the ticket it self, by making a "change()" method, receiving a changeCommandModel (or something like this), so you can define the business rules inside your domain object.
if (DTO.Status != null && dto.Status == "RESOLVED")
supportTicket.Resolve(DTO.title);
I will change the underlying method to take title as parameter, this clarify the resolve action. That second if and validation you want in the domain method. It's really preference, more importantly is the message and I agree with #VoiceOfUnreason second option.

MVVM design: Blocking MessageBox in ViewModel

This question refers to a WPF application based on PRISM 5.0 and the MVVM pattern.
Sometimes when users make decisions, that could have unwanted or negative consequences, it is very common to ask the user, if he really wants to go on and proceed.
For example:
One common way, is to ask the user with a messagebox, if he really wants to delete data, that can not be restored after deletion.
The problem is:
If I call the MessageBox inside the ViewModel, the ViewModel becomes untestable from the outside.
//BAD!
public class ViewModel
{
public Boolean Delete()
{
//Blocking and therefore untestable in automatic UnitTests
MsgBoxResult result = MsgBox.Show("Do you really want to delete?");
if (result == yes) {//Do stuff that deletes data here;}
}
}
One possibility would be, to ask the question in a different private method, that calls the public method
//BETTER, BUT OK?
public class ViewModel
{
private void OnDeleteAction
{
MsgBoxResult result = MsgBox.Show("Do you really want to delete?");
if (result == yes) {Delete();}
}
public Boolean Delete()
{
//Testable from the outside again, because no blocking question
//Do stuff that deletes data here
}
My question: Is is this a good way or is there a more elegant way to ask the user inside a ViewModel? Can you give me a hint or link, what is the best for PRISM 5.0?
I know, that a rule of thumb is, not to use any UI elements in the ViewModel, but I see no alternative to a blocking MessageBox or something else, that blocks the process, before proceeding.
Thank you any hints!
There are two alternatives that I know of which can reduce coupling between View and ViewModel: using an interaction service, and firing interaction requests. Both are explained very well here; you might want to take a look.
The general idea is that you abstract how asynchronous interactions are done and work with something more similar to event-based logic while at the same time allowing the ViewModel to express that it wants to interact with the user as part of an operation; the net result is that you can document this interaction and unit test it.
Prism Interactivity is the way to go here. This allows you to do Confirmations, Notifications, and create custom dialogs that work well with the MVVM pattern. I use them successfully in my Prism applications.
Here are some links to some code in the Prism repo on GitHub:
Notification Request
Confirmation Request
Custom Content
Custom Request

How to "refresh" my ViewModels after database changes have been done in another ViewModel?

I'm currently writing a rather small desktop application using the MVVM Approach. It also utilizes Entity Framework 6 for the database access. Right now, my top-level ViewModel instantiates the 'smaller' ones, and passes them the DbContext I'm using. The smaller ViewModels I use correspond to UserControls sitting in a separate TabItem each. But if I change something in the database in one tab and switch the tab afterwards, the UI isn't keeping up, logically, since there is no OnPropertyChanged("SomeObservableCollection") Happening.
I thought about just "refreshing everything inside" when a TabItem becomes active, but on one hand, I don't know how to do this (it would basically be doing OnPropertyChanged(..) for every UI-relevant property, right?), and on the other hand, it does seem neither elegant nor 'correct'.
What should I do about this? And is using one global DbContext even good practice? I read about short-lived DbContext instances being better, but I also found the opposite statement regarding desktop applications...
How do you handle this scenario? It can't be that rare actually, can it? Thanks!
You have to look at using a Messenger (MvvMLight) or EventAggregator (Caliburn.Micro).
So when your context has changed you pass the message about it and update your SomeObservableCollection so OnPropertyChanged("SomeObservableCollection") will be raised.
Might Help . I have done this in small project . any better solutions are welcomed.
**Viewmodel 1 Where changes occurs**
//database call
string result = _dataService.Insert(data);
if(result=="Success")
{
//notify viewmodels using default messenger instance
MessengerInstance.Send(new NotificationMessage("notifycollection"));
}
Viewmodel 2 where we receive notification
public AssignTimeSlotViewModel(IDataService dataService)
{
// registering the notification
MessengerInstance.Register<NotificationMessage>(this, receiveNotification);
}
#region Messenger - receivers
private void receiveNotification(NotificationMessage msg)
{
if (msg.Notification == "notifycollection")
{
/// Call Database to keep collection updated.
// raise propety changed event if neccessary.
// Do Something
}
}
#endregion
Thats not an easy subject at all.
If you handle with a small amount of data and performance is not a problem for you, you could update your bindings every time the view gets loaded. Here you can see how to accomplish that.
A Problem if you do that is, that you have to do some extra logic for saving last selected items and reselect them after the view gets loaded.
Using a messenger could be an option too. But in my experience the messenger could make thinks messy if it is not implemented correctly. For example please dont use some magic strings as messeages.

Injecting IOrderSender into domain object

I have been pondering this for a while. In general I try to stay away from injecting services into my domain, but I have this case:
I have an PurchaseOrder object. This order is sent to a supplier using some service (Email or webservice). After the order is sent, a confirmation should be sent to the user that made the order.
So I realised this is a case where Domain Events would be a nice way of implementing this publishing an PurchaseOrderMade - event.
Then I came to think:
Is the order really made if the order wasnt sent?
You haven't made an order just because you decided to do it and wrote it down, but the order is made at the time when you have conveyed it to the supplier according to contract without errors.
So I redecided and thought that this might belong to the domain after all so I should send it by injecting a IPurchaseOrderSender to my domain and then publish an OrderMadeEvent after the successfull transaction and sending a confirmation in the EventHandler.
The reasoning is this:
The sending of the order IS crucial part of the process and could cause state to alter (i.e. setting a flag that the order is sent)
The confirmation is NOT crucial, should this fail the order is still made and everything would go as planned.
It is easy to read, and to alter implementation of an IOrderService
The questions are:
Is this really so bad to do?
Does it break principles of DDD?
Have you encountered this before and solved it in a better way?
Here is the code:
public void MakeOrder(PurchaseOrder order, IPurchaseOrderSender orderSender)
{
if(PurchaseOrders == null)
PurchaseOrders = new List<PurchaseOrder>();
PurchaseOrders.Add(order);
orderSender.Send(order);
DomainEvents.Raise(new PurchaseOrderIsMade(){Order = order});
}
public interface IPurchaseOrderSender
{
void Send(PurchaseOrder order);
}
I encountered this before, here is what I did:
Split the local transaction with the remote procedure call.
I think it's not a big deal if the order sending fails. In this case, either the order is placed but not set to "sent" or the order is rollbacked. The business operator can intervene if the order is not send or the customer will call if the order is not placed.
But it's annoying if there is something wrong with the transaction after sending the order successfully. In this case, if the order is rollbacked, the intervention is more difficult because we lost the supplier's notification. The notification usually contains an supplier's order identifier, therefore we could cancel the order with this identifier if necessary.
So we decide to use messaging.
1) The PlaceOrderService is responsible for storing the order and sends a message.
2) The consumer of the message sends the order to the suppler and sends a message containing the supplier's notification.
3) The other consumer of the notification message update the order state.
Each step modifies only one aggregate or just call the remote.
Hope this helps.
Update
1.How would you implement the messaging part here
I adopt the solution mentioned in Eric Evans' dddsample, ApplicationEvents. It's just a simple interface and an jms implementation, something like
public void placeOrder(...) {// method in application service
....//order making
orderRepository.store(order);
applicationEvents.orderWasPlaced(order);//injected applicationEvents
//better move this step out of transaction boundary if not using 2pc commit
//make the method returnning order and use decorator to send the message
// placeOrder(...) {
// Order order = target.placeOrder(...);//transaction end here
// applicationEvents.orderWasPlaced(order);
// return order;
// }
}
public class JmsApplicationEvents implements ApplicationEvents {
public void orderWasPlaced(Order order) {
//sends the message using messaging api of your platform
}
}
2.I see you mention suppliers notification, but let's assume this is done through email (which will be the primary scenario here) I would
like to know that the transaction was performed without errors (i.e.
no smtp or connection failure), but cannot rely on a response that the
order was actually received would that change anything?
hmm.. I have never build an trading application based on email, but here is my suggestions:
Messaging solution still fits if you need strong consistency. Messaging is transactional and could involve in global transaction while email doesn't.
Messaging provides more availability (your order making will not fail even if the mailserver is down) and scalability(queues).
Failure handling is more difficult in messaging solution, usually needs compensating actions. And it's more difficult for the user to get the processing information. For example, you have to notify the user about the progress of the order processing since the following steps are asynchronous. And an email should be sent to the customer if the order is rejected by the supplier.
But messaging does add extra complexity and takes you more effort to build and maintain. You have to evaluate is the gain worth the cost. Actually, I have also built several systems in synchronous solution(they don't require high throughput and availability), they works fine most of the time, only less than ten of orders fail due to the connection problem within a year, so it's not worthy to build an automatic error handling mechanism at all.

Model view presenter, how to pass entities between view?

Edit : Accepted Chris Holmes response, but always ready to refactor if someone come up with a better way! Thanks!
Doing some winforms with MVP what is the best way to pass an entity to another view.
Let say I have a CustomerSearchView/Presenter, on doubleClick I want to show the CustomerEditView/Presenter. I don't want my view to know about the model, so I can't create a ctor that take an ICustomer in parameters.
my reflex would be,
CustomerSearchView create a new CustomerEditView, which create it's own presenter.
Then my CustomerSearchView would do something like :
var customerEditView = new CustomerEditView();
customerEditView.Presenter.Customer = this.Presenter.SelectedCustomer;
Other possible approach would be a CustomerDTO class, and make a CustomerEditView that accept one of those CustomerDTO, but I think it's a lot of work something simple.
Sorry for basic question but all example I can find never reach that point, and it's a brownfield project, and the approach used so far is giving me headache...
I don't know exactly how you are showing your views, so it's a bit difficult to give you specific advice here. This is how I've done this sort of thing before:
What we did was have the CustomerSearchViewPresenter fire an event like OpenCustomer(customerId). (That is assuming that your search view only has a few pieces of Customer data and the customerId would be one of them. If your search view has entire Customer objects listed then you could call OpenCustomer(customer). But I wouldn't build a search view and allow it to populate with entire objects... We keep our search views lightweight in terms of data.)
Somewhere else in the application is an event handler that listens for the OpenCustomer() event and performs the task of creating a new CustomerEditView w/ Presenter (and I'm going to defer to my IoC container do this stuff for me, so I don't have to use the "new" keyword anywhere). Once the view is created we can pass along the id (or customer object) to the new CustomerEditView and then show it.
This class that is responsible for listing the OpenCustomer() event and performs the creation of the CustomerEditView is typically some sort of Controller class in our app.
To further simplify this situation, I've done this another way: I create both the CustomerSearchView (& presenter) and CustomerEditView (& presenter) when the application or module starts up. When the CustomerSearchView needs to open a Customer for editing, the CustomerEditView becomes the responder to the OpenCustomer event and loads the data into itself, and knows how to show itself in whatever container it is supposed to do.
So there's multiple ways to do this.
How about:
//In CustomerSearchPresenter
var presenter = new CustomerEditPresenter();
var customerEditView = new CustomerEditView(presenter);
presenter.SetCustomer(customer);
//In CustomerEditPresenter
public void SetCustomer(customer)
{
View.Name = customer.Name;
View.Id = customer.Id;
...
}
In think your customer search view should just delegate to its presenter you need to have an action execute.
There are a couple of crucial insights to get a natural flow in any MVP code:
It's the presenter that drives the view, not the other way around.
Because of 1. the view need not know about the presenter's existence. Less dependencies usually means easier maintenance.
In C#, I find events being a great asset when decoupling presenters from views. More details in a previous answer: Model-View-Presenter in WinForms
I would look at MS Prism 4, and their nice Navigation interface. Also look at Silverlight and WCF Navigation. They are well done and handle things like prompting the user for confirmation from "dirty" forms, with cancellation.
I would look at the PageFunction() documentation in WCF as well, for how to "call" a page from another, and get back info.
Here's how it works (javascript, sorry):
User double-clicks customer on customer list:
CustomerList.onDblClick(customerId){
app.fireEvent('customerEditRequest', id)
}
...
app.onCustomerEditRequest(id){
this.mainRegion.requestNavigate('customers/edit', id);
}
If navigation to edit view was successful...
CustomerEditView.onNavigatedTo(context){
this.model.load(context.parameters.id));
}
CustomerEditView.onSaveButtonClick(){
this.model.save();
app.fireEvent('customerEdited', id);
}
...
app.onCustomerEdited(id){
app.mainRegion.requestNavigate('customerlist', id);
}
There are a few different ways you could do it:
send a callback function to the edit form, from the customer list. edit form will call it, and you do what you want when it's called.
have the edit form raise on "customerEdited" event that you listen to and react to (no app-wide bus)
use an application-wide Event Bus to manage the events centrally, shown.
I used to have my views communicate with their presenters, but have moved away from that. It doesn't conform to the original definition of a pattern (not a reason in itself for deviating just a contributing factor to exact those benefits). Views ideally should be kept as dumb and with as few dependencies as possible. View should communicate w/ Presenter (any "observers") via delegates/events/some "fire-and-forget" mechanism. As a matter of fact, I've introduced a controller into MVP specifically to intercept View events and either re-fire to presenter (rarely) to communite w/ Presenter, or to communicate with a system or Presenter-specific event bus - enabling me to change user action alerting mechanisms w/out touching the view. Have to be careful with an event bus though; pretty soon you start throwing all events in there, app gets chatty/bogged down in handling events, and events aren't the fastest things in .Net. Sunchronization is an added concern, esp if ur app need to have a more "conversational" interaction with your user.
Should bear in mind that although Presenter is usu view/process-specific, views (and view-models) can be reused; having the View in a containment/delegation relationship with the Presenter strongly couples View/limits its reuse. This could be reduced by some DI, but I find DI containers to be unnecessary complexity in most cases (since I have to know how to create objects anyway and how often do you change out an object for another semantically similar one after creating/testing it?). Concrete dependency goes nowhere except another layer/adds more obscurity/makes things more difficult to debug/trace. Been on a "simplicity" kick lately though, and mostly prefer to do my on Factory/object creations/ORM mappings for most apps, since there's usu a "1-to-1" btw db tables/entities and n need for the added complexity of a generic 3rd-party ORM tool that by taht generic context/needing to serve different apps has to make things harder than they need to be, even if u understand how they work (not the point).
Moreover, it's still quite feasible for View to observe Model in MVP (as in MVC), so I wouldn't be so quick to rule this out. I don't prefer to do this myself, but it' doesn't "break" the pattern. Matter of fact, I developed something similar to MVP about a decade ago because I didnt like the "circular loop" btw the MVC components (View knowing about Model); I preferred to have the cleaner separation btw View and Model that all these patterns (including MVC) professed, as well as a desire to keep View as dumb as possible (observing Model woujld mean View would need more intelligence to process Model changes). What I ended up doing was something like MVVM and strategy patter, where I used "substructures" of the model to pass in to the View, serving as "change notifiers". This kept everything view purpose-specific and flexible/reusable (tough combo).

Categories