DDDSample, should there be a repository.save in controller? - c#

I am looking at the DDD Sample for .net provided by DDD sample at Codeplex and trying to understand how the various layers work with DDD.
With the sample, I can see when a new Cargo is created the aggregate root Cargo is stored via the repository in the BookingService.BookNewCargo() call. However, when I assign a new route or change a destination (AssignCargoToRoute() or ChangeDestination() calls in BookingService) I expected a CargoRepository.Store() to be called as well.
Code sample using Nhibernate which I have not used before.
What am I missing?
In other words, how is the aggregate getting persisted if Store() is not called?
JD

hm, i've seen a number of switch statements in the domain, seems like there are a few core terms missing in the domain. at first glance a number of areas seem to have quite a bit of ceremony, but hey, it's just a first impression.
udi dahan's domain events pattern has been used here, there is an event handler "cargo has been assigned to route" which seems to store the object in question. watch out for usages of the domainevents class in combination with the proper event class, i hope that will tell you what triggers the store.

Here is a sample application I wrote:
http://clientdatasystem.codeplex.com/SourceControl/list/changesets
And here is my accompanying blog:
http://lucidcoding.blogspot.com/2011/10/enterprise-software-architecture-how-to.html
As you may note in my blog, I don't describe it as DDD, but as following the Domain Model pattern. It is simpler than the Cargo application, and may suit your needs better. I follow the pattern of create and save, and also update and and save that you were expecting. I'm not saying my sample is better than Eric Evans's (I wouldn't dare!) but the Cargo Application is not completely a basic, stripped down version.

Related

To use or not to use Repositories with an ORM

There are many voices saying that in this age of ORMs, there is no longer need for repositories. Recently I was thinking about it myself and their arguments made usually sense to me.
On my new project, using EF Core, I thought I try the no-repository approach to make things more straightforward and simple. Simplicity is always good, after all.
Things went pretty well, until I realized I often write things like this (this is not a real aggregate, just an artificial example):
ctx.Invoices.Include(x => x.User).ThenInclude(x => x.Address).Include(x => x.Items).FirstOrDefault(x => x.Id == id);
Alright, so every time I need to get an aggregate, I need to write this statement and there are chances, sometimes/someone will forget to include an important reference.
What about to put this code to a helper class?
class InvoiceHelper
{
public Invoice FindById(int id) {...}
}
Isn't this just a start of a repository in disguise? So even with an ORM, I still find repositories kinda useful.
How do others do these things and still appear to be happy without repositories?
Some articles discussing no-repository approach:
https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/
https://rob.conery.io/2014/03/03/repositories-and-unitofwork-are-not-a-good-idea/
https://cockneycoder.wordpress.com/2013/04/07/why-entity-framework-renders-the-repository-pattern-obsolete/
If you believe in the rule of thumb "don't mock what you don't own", I fail to see how you could substitute your ORM functionality for a mock or stub in your tests without a Repository-like abstraction.
Repository is a very important seam - adapter in Hexagonal parlance - between your application and storage.
And yes, the fact that you needed to create a helper to factor in some data fetching behavior is a perfect illustration of that importance.
[Edit] Thoughts on the "no repos" articles
As often, most of the "repository backlash" is overreaction to misuse of Repository and UoW rooted in collective amnesia of the original reasons behind the patterns.
"Why hide a perfectly good framework ?" - EF is not!
For instance, IDbSet mentioned by one of the articles is a walking leaky abstraction, from its very name to Attach() to all its extension methods. Also see below misuses and misunderstandings of methods like Update() provided by the "perfectly good framework".
In contrast, the point of the original Repository pattern was to be a minimalist 3-method collection-like abstraction you can't go wrong with. Add(), Remove() and a few Get methods are all we need, not the bells and whistles of a whole framework.
"Repository doesn’t make testing any easier" : yes it does! The smaller the contract of a dependency, the easier it is to reason about, test, debug. A.k.a. KISS.
"1. Performance – sort/filter: Microsoft’s old (2013) implementation of the Rep/UoW’s has a method called GetStudents that returns IEnumerable. This means any filtering or sorting is going to be done in software, which is inefficient."
Seriously? The lousiness of Microsoft tutorial sample code written years ago is the #1 drawback about a whole pattern? When you just have to create a method inside the repo implementation and it can be as optimized as you need!
A Rep/UoW would update an entity using the EF Core’ Update method - Says who? A straw man again. I've been using these patterns for 10+ years and never needed that method. SaveChanges() has always been the way to go.
The allure of the Rep/UoW comes from the view that you can write one, generic repository then you use that to build all your sub-repositories
Absolutely not. This was not part of the original pattern and even largely identified as an anti-pattern in the community since the early days of DDD adoption.
"Option 2 - DDD-styled entity classes"
aka domain classes that do data access... which destroys persistence ignorance. Not really a good idea IMO.
I could go on and on about almost every argument there, but the gist of it is :
If you're going to blame a pattern, do it in full understanding of its fundamentals, not because you don't like some broken implementation that's been copy pasted and cargo culted along generations of developers to the point of uselessness.

Should command info be passed to aggregate using method parameters or by reference?

I'm working on implementing a basic CQRS+ES application. I've seen many examples but I don't understand the routing between the command handler and aggregate.
In some examples, the work is did in this way:
XCommandHandler:
void Handle(XCommand command) {
var aggregate = this.repository.Find<Aggregate>(command.aggId);
aggregate.InvokeSomeBusinessLogic(command.property1, command.property2);
this.repository.Save(aggregate);
}
But others do in another way:
XCommandHandler:
void Handle(XCommand command) {
var aggregate = this.repository.Find<Aggregate>(command.aggId);
aggregate.InvokeSomeBusinessLogic(command);
this.repository.Save(aggregate);
}
What is the best approach, especially when you have many properties (15 or more) in a command?
This isn't particularly a question about CQRS+ES, but just about API design overall. As Clean Code explains, a method with no parameters is better than a method with one parameter, which is better than one with two parameters, etc.
Blindly following that rule should always make you select your second option:
aggregate.InvokeSomeBusinessLogic(command);
However, blindly following any rule is rarely a good idea. In this case, it would be a good idea to consider the Interface Segregation Principle as a countering force:
Clients should not be forced to depend on methods they do not use.
Since getters and setters are methods too, I think this principle applies to Command Objects as well.
Thus, if you have 15 or more properties, but the method in question only needs two of them, perhaps it would be better to just pass those two values.
Another thing entirely is that if you have a Command Object with 15 properties, you may want to rethink your design. One of the fundamental assumptions behind CQRS+ES is that applications present task-based UIs, which ensures that each Command (and the corresponding Events) are 'small'.
Editing in Mark's comments with links because one of the links were broken:
Updating aggregate info isn't task-based; it's CRUD. Perhaps these two articles from Udi Dahan will be helpful.
Queries, Patterns, and Search – food for thought
Tasks, Messages, & Transactions – the holy trinity
I would agree with Mark in principle. I would note however that CQRS has grown from the domain driven design world. They stress the importance of language (ubiquitous language). You can capture the intent and meaningfulness in the actual name of the command object.
On a practical level refactoring methods by adding parameters can become a real pain if called from more than a few places. This can be significantly eased with a single object.
I have a couple of related posts that you may find helpful. Aggregate Root – How to Build One for CQRS and Event Sourcing and 6 Code Smells with your CQRS Events – and How to Avoid Them. While the last one is about events many of the principles apply.
Hope you find them helpful.

Autogenerate C# WebApi from Models

Does anyone know of any tools that can generate a C# WebApi REST Interface for a model?
What I would like is to define my model and add attributes that describe properties of the resource in the context of standard REST architecture. After defining the model and adding attributes, the hypothetical tool would generate all the code needed for implementation.
I'm not 100% sure if this tool will work for your very specific case, but it is a code generator nonetheless and appears to be relatively versatile.
http://www.codesmithtools.com/product/generator
I'm assuming you already searched for a code generator to suit your need so if this one doesn't work for you, you may have to face the music and write one yourself.
A co-worker I work with here wrote a generator in C# that pulled schema/data structure info from a SQL database, took that info, and simply output C# code to a .cs file.
I know this isn't the best answer, but hopefully it helps in at least some way. :)
Use OData to create simple rest services(GET, POST, PUT, DELETE). OData is being widely accepted by many UI components which allow us to use dynamic querying at request level.
You can simply replace the Model Names and DTO Names in an odata controller to use it to other model's controller.

Design pattern for workflow

I don't think this is a duplicate but I actually need some one wise to confirm my question.
My pattern is going to be similar too (albeit much more complex) the picture below (where my application starts from top to bottom).
It takes a complex object as part of the constructor and then goes through various processes (saved in different .dlls).
I've not taken on a project like this before and want to get it right - I know design patterns are designed to help and give guidance.
My question, what patterns could work. I am stuck on .NET 2.0. My research suggests sequence pattern.
So, am I limited to only the sequence pattern or does any one have another other suggestion?
I have written similar code, but not just with a single pattern. Initially my approach was to code all in Transaction Script pattern and then refactor. During refactoring I came across follwings;
Template pattern: Decoupled logic to seperate classes which I called an Activity (similar to WF), and these Activity classes behaved similar way and therefore used Template pattern.
Transaction Script pattern: An Activity itself is a Transaction Script and could accept Arguments, has a Fault property, and Results which it will be used, construct, stored during the execution.
Builder pattern: To wire up all the Acitivity classes for the business scenario, I ended up with Builder pattern.

C# Where to place code that retrieves GUI data?

I'm puzzling with where to place some code. I have a listbox and the listitems are stored in the database. The thing is, where should I place the code that retrieves the data from the database? I do already have a database class with a method ExecuteSelectQuery(). Shall I create Utility class with a method public DataTable GetGroupData() ? /* group is the listbox */ This method then calls the method ExecuteSelectQuery() from the database class.
What should I do?
There are many data access patterns you could look at implementing. A Repository pattern might get you where you need to go.
The idea is to have a GroupRepository class that fetches Group data. It doesn't have to be overly complicated. A simple method like GetAllGroups could return a collection you can use for your ListBox items.
You could simply abstract the database code into a utility class, as you suggest, and this wouldn't be a terrible solution. (You probably can't get much better with WebForms.) Yet if the system is going to end up quite complicated, then you might want to pick a more formal architecture...
Probably the best option for ASP.NET is the ASP.NET MVC Framework, which fully replaces WebForms. It's built around the Model-View-Controller architecture pattern, which is designed specifically to clearly separate code for the user interface and backened logic, which seems to be exactly what you want. (Indeed, it makes the design of websites a lot more structured in many ways.)
Also, if you want to create a more structured model for your database system, consider using an ORM such as the ADO.NET Entity Framework. However, this may be overkill if your database isn't very complicated. Using the MVC pattern is probably going to make a lot more difference.
consider adding a layer between your UI and data access layers. There you can implement some kind of caching if the data is not being changed frequently - this way you will avoid retrieving multiple times the same data from the DB.
I would recommend you the Application Architecture Guide book.
Pavel
Looks like you already have the data access layer implemented via your database class. I guess the confusion right now is in implementing the presentation and business layers. To me 'GetGroupData' is more of a part of the Business layer and is the right thing to implement. It will allow you to make changes in future with minimal or no impact to the presentation layer. Therefore, the flow that you suggested looks right. LoadListBox followed by GetGroupData followed by ExecuteSelectQuery.

Categories