Rich domain model. Anti anemic domain model - c#

A lot of discussions, like this and this, go with RICH DOMAIN MODEL
and there are 2 strong reason about amenic, like 1 and 3:
Now let's say that I need to make sure that I need to validate that
the product exists in inventory and throw exception if it doesn't.
so there is a question: If we don't need an object to be dependent on ISomeRepository like service, can we just make this:
public void Order.AddOrderLine(IEnumerable<Product> products, Product product)
{
if(!prosucts.Contains(product))
throw new AddProductException
OrderLines.Add(new OrderLine(product));
}
and call it like this:
Order.AddOrderLine(ISomeRepository.GetAll(), product);

It sounds like there's a missing concept in your domain here. I'd think about introducing some kind of StoreInventory entity, such that products move out of the inventory and into an order (this is called 'picking' in many commerce domains).
interface StoreInventory
{
IEnumerable<Product> AvailableProducts { get; }
Product PickProduct(guid productId); // This doesn't have to be an Id, it could be some other key or a specification.
}
void Order.AddOrderLine(StoreInventory inventory, Product product)
{
if (!inventory.AvailableProducts.Contains(product.Id))
throw new AddProductException();
var item = inventory.Pick(product);
OrderLines.Add(new OrderLine(item);
}
This would seem to be more closely aligned to reality to me. But as always in DDD, only your domain experts can tell you how things are supposed to flow.
This also seems more extensible in the future, for example with this model it would be easy to introduce multiple stores - each with their own inventory.

If you read about DDD, you would see that Repository is core concept of DDD. In DDD, repository is part of domain and says what kind of behavior the domain requires from it's persistence to work. In your case, you could simply pass the repository into the method and have the method pull the necessary data.
public void Order.AddOrderLine(ISomeRepository repo, Product product)
{
if(!repo.ProductExists(product))
throw new AddProductException
OrderLines.Add(new OrderLine(product));
}
// call it like
Order.AddOrderLine(someRepository, product);
I think the problem of your confusion is that repository, or more precisely, it's abstraction, is often tied to the persistence itself. Which is actually misconception caused by misunderstanding of the whole pattern. Correct repository consists of 2 parts: the abstraction, usually represented by interface, which defines what kind of operations the domain requires from the persistence. And the concrete implementation, that implements those operations over used persistence technology.

Related

Implementing a domain service with DDD in C#

I'm working on a domain model writing my software all DDD and stuff doing a great job, when I suddenly bump into the same problem I have been facing over and over again and now it's time to share some insights. The root of the problem lies in the uniqueness of data.
For example, let's say we're writing this awesome domain model for a user. Obviously the username is unique and just to be as flexible as possible we want the user to be able to change his name, so I implemented the following method:
public void SetUsername(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new UserException(UserErrorCode.UsernameNullOrEmpty,
"The username cannot be null or empty");
}
if (!Regex.IsMatch(value, RegularExpressions.Username))
{
throw new UserException(UserErrorCode.InvalidUsername,
"The username {value} does not meet the required ");
}
if (!Equals(Username, value))
{
Username = value;
SetState(TrackingState.Modified);
}
}
Again, this is all fine and fancy, but this function lacks the ability to check if the username is unique or not. So writing all these nice articles about DDD, this would be a nice use-case for a Domain Service. Ideally, I would inject that service using dependency injection but this ruins the constructor of my domain model. Alternatively, I can demand an instance of a domain service as a function argument like so: public void SetUsername(string value, IUsersDomainService service) and to be honest I don't see any solid alternatives.
Who has faced this problem and maybe came up with a nice rock-solid solution?
I agree with #TomTom. But as most times with software decisions, it depends, there is almost always a tradeoff. As a rule of thumb, you gain more by not injecting a domain service into an entity. This is a common question when one is starting with DDD and CQRS+ES. And has been thoroughly discussed in the CQRS mailing list here
However, there are some cases where the approach you suggested (known as method injection) might be beneficial it depends on the scenario. I’ll try and drive some analysis points next.
Consider the case where you want to make some validation before creating an entity. Let's think of a hypothetical and way oversimplified international banking context, with the following entity:
public class BankNote
{
private BankNote() {}
public static FromCurrency(
Currency currency,
ISupportedCurrencyService currencyService)
{
currencyService.IsAvailable(currency);
}
}
I am using the factory method pattern FromCurrency inside your entity to abstract the entity creation process and add some validation so that the entity is always created in the correct state.
Since the supported currencies might change overtime, and the logic of which currencies are supported is a different responsibility than the bank note issuing logic, injecting the ISupportedCurrencyService in the factory method gives us the following benefits:
By the way, the method dependency injection for domain services is suggested in the book: Hands-On Domain-Driven Design with .NET Core
By Alexey Zimarev. Chapter 5 "Implementing the Model" page 120
Pros
The BankNote is always created with a supported Currency, even if the currencies supported change overtime.
Since we are depending on an interface instead of a concrete implementation, we can easily swap and change the implementation without changing the entity.
The service is never stored as an instance variable of the class, so no risk of depending on it more than we need.
Cons
If we keep going this way we might add a lot of dependencies injected into the entity and it will become hard to maintain overtime.
We still are adding a loosely coupled dependency to the entity and hence the entity now needs to know about that interface. We are violating the Single Responsibility Principle, and now you would need to mock the ISupportedCurrencyService to test the factory method.
We can’t instantiate the entity without depending on a service implemented externally from the domain. This can cause serious memory leak and performance issues depending on the scenario.
Another approach
You can avoid all the cons if you call the service before trying to instantiate the entity. Say having a different class for the factory instead of a factory method, and make that separate factory use the ISupportedCurrencyService and only then call the entity constructor.
public class BankNoteFactory
{
private readonly ISupportedCurrencyService _currencyService;
private BankNoteFactory(
ISupportedCurrencyService currencyService)
=> _currencyService = currencyService;
public BankNote FromCurrency(
Currency currency)
{
if(_currencyService.IsAvailable(currency))
return new BanckNote(currency);
// To call the constructor here you would also need
// to change the constructor visibility to internal.
}
}
Using this approach you would end with one extra class and an entity that could be instantiated with unsupported currencies, but with better SRP compliance.

How to deal with MVC ViewModel - Domain Model - Entity in MVC controllers and services

We are writing a MVC data maintenance application is part of a larger project. We try to use domain-driven design DDD.
There are already other questions about this on SO, like here, here and here.
Yet they don't fully answer my question.
We also have bounded contexts in the data layer, since the database has 755 tables. So we created bounded contexts for business, roles, products, customers, etc.
The problem we have is that in the MVC application we have a view for "intial setup" which uses a ViewModel that in the end spans multiple bounded contexts (using IUnitOfWork pattern in Entity Framework 6).
That view must therefore write to the business context, and roles context.
The domain model would have a Business model and an Address model and a few other models in a larger pbject graph.
The ViewModel is a flattened, simplified model of these two and other domain models:
public class InitialSetupViewModel
{
string BusinessName{get;set;}
string Street{get;set;}
string Street2{get;set;}
string State{get;set;}
string ZIP{get;set;}
...
}
This ViewModel should map to the domain models, which we are doing with Automapper.
The controller gets the domain service injected:
public class SetupController : Controller
{
private readonly IMaintenanceService service;
public SetupController( IMaintenanceService maintenanceService = null )
{
service = maintenanceService;
}
public void Create(...????....)
{
service.CreateBusiness(..?.);
}
}
Problems:
The service can't know about the InitialSetupViewModel, so what should be passed to the service?
The service must know about the BusinessDbContext and RolesDbContext. So I must call SaveChanges() on both, which beats the purpose of having a single IUnitOfWork. Do I have to create yet another UnitOfWork that includes both business and roles entities?
I don't think it's justifiable to combine these two IUnitOfWorks into one just to make this MVC view work. But what is the solution?
Thank you!
It's always hard to have a strong opinion about a domain you don't know, but here it goes:
As has been commented already, the Controller should assume responsibility for mapping between view and domain models, DTOs or what have you. It could take an instance of InitialSetupViewModel as input, but implementation details may vary.
It is true that remodeling the domain may be the correct choice if you find yourself in need of otherwise breaking the borders of your bounded contexts. Focusing just on the Unit of Work pattern though, I don't quite get your hesitation.
It is the responsibility of a Unit of Work implementation to keep track of all the domain objects that need to be in sync within one transaction. There is nothing odd about the same domain object(s) being involved in several different Units of Work. This does not mean that you should combine "smaller" Unit of Work implementations into "larger" ones when you're dealing with another type of aggregate, but including both "roles" and "businesses" in one Unit of Work, sure.
Doing this should not be enticed by what your view looks like, but by what is "true" in your domain model(s), and rather than dealing just with collections of domain objects, your domain should probably describe suitable aggregates.
Maybe it's even OK to store each domain object with separate transactions (Units of Work), i.e. if synchronizing them is not necessary -- e.g. it's still fine if (or perhaps even desired that) failing to persist Business does not stop Roles from getting through or vice versa. Actually, I think one could even argue that if the bounded contexts are in fact correctly defined, this should be the case.
I hope these comments help.
Martin Fowler on Unit of Work and Aggregates.

Design Pattern For Persistence

I am working on a project where I am wrestling with trying to move from one persistence pattern to another.
I've looked in Patterns of Enterprise Application Architecture, Design Patterns, and here at this MSDN article for help. Our current pattern is the Active Record pattern described in the MSDN article. As a first step in moving to a more modular code base we are trying to break out some of our business objects (aka tables) into multiple interfaces.
So for example, let's say I have a store application something like this:
public interface IContactInfo
{
...
}
public interface IBillingContactInfo: IContactInfo
{
...
}
public interface IShippingContactInfo: IContactInfo
{
...
}
public class Customer: IBillingContactInfo, IShippingContactInfo
{
#region IBillingContactInfo Implementation
...
#endregion
#region IShippingContactInfo Implementation
...
#endregion
public void Load(int customerID);
public void Save();
}
The Customer class represents a row in our Customer Table. Even though the Customer class is one row it actually implements two different interfaces: IBillingContactInfo, IShippingContactInfo.
Historically we didn't have those two interfaces we simply passed around the entire Customer object everywhere and made whatever changes we wanted to it and then saved it.
Here is where the problem comes in. Now that we have those two interfaces we may have a control that takes an IContactInfo, displays it to the user, and allows the user to correct it if it is wrong. Currently our IContactInfo interface doesn't implement any Save() to allow changes to it to persist.
Any suggestions on good design patterns to get around this limitation without a complete switch to other well known solutions? I don't really want to go through and add a Save() method to all my interfaces but it may be what I end up needing to do.
How many different derivatives of IContactInfo do you plan to have?
Maybe I'm missing the point, but I think you would do better with a class called ContactInfo with a BillTo and a ShipTo instance in each Customer. Since your IShippingContactInfo and IBillingContactInfo interfaces inherit from the same IContactInfo interface, your Customer class will satisfy both IContactInfo base interfaces with one set of fields. That would be a problem.
It's better to make those separate instances. Then, saving your Customer is much more straight-forward.
Are you planning on serialization for persistence or saving to a database or something else?
Using a concrete type for Customer and ContactInfo would definitely cover the first two.
(A flat file would work for your original setup, but I hope you aren't planning on that.)
I think it all comes down to how many derivatives of IContactInfo you expect to have. There is nothing wrong with a bit more topography in your graph. If that means one record with multiple portions (your example), or if that is a one-to-many relationship (my example), or if it is a many-to-many that lists the type (ShipTo, BillTo, etc.) in the join table. The many-to-many definitely reduces the relationships between Customer and the various ContactInfo types, but it creates overhead in application development for the scenarios when you want concrete relationships.
You can easily add a Save() method constraint to the inherited interfaces by simply having IContactInfo implement an IPersistable interface, which mandates the Save() method. So then anything that has IContactInfo also has IPersistable, and therefore must have Save(). You can also do this with ILoadable and Load(int ID) - or, with more semantic correctness, IRetrievable and Retrieve(int ID).
This completely depends on how you're using your ContactInfo objects though. If this doesn't make sense with relation to your usage please leave a comment/update your question and I'll revisit my answer.

Repository pattern and/or/vs business logic layer

I have a problem I want to know your opinion.
I am trying to use Repository Pattern. I have a repository object which load data to a POCO. I have also created a Business logic layer which adds a little bit of functionality but basically wraps the POCO. So in the end I have a BLL which loads DAO with usage of repository.
I am not very happy with this solution. I have a three layers but I feel that BLL is not providing enought functionality to keep it there. On the other hand I do not want to put my logic in the repository layer nor data access layer?
So my question is where should I put logic for application? Which solution do you use(DAO + repo or DAO + BLL + rep or any other)?
There are two basic ways to think about business rules when designing your domain.
1.) The domain entities are basic POCO/DTOs. And you hand them off to domain services. These services could be as simple as another class, or they really could be actual services sitting on another server.
var user = repository.Find(x => x.UserName == userName);
if (userLogonService.IsValidUser(user, password)) {
userLogonService.UpdateUserAsLoggedOn(user);
}
repository.SaveChanges();
2.) The domain entities contain their own operation logic. This is closer to what many MVC patterns will follow. And since you asked, this is the model that I prefer.
var user = repository.Find(x => x.UserName == userName);
if (user.CheckPassword(password)) {
user.LogOnNow();
}
repository.SaveChanges();
Both are completely valid patterns. #1 has a discrete business operation tier, but suffers from an Anemic Domain Model. #2 can lead to big domain entities if you domain starts to become complicated, or if a model can do a lot of things.
EDIT #1: Response to John Kraft
Oven.Bake(myPizza) vs. myPizza.Bake()
I mostly agree. Do you have a single Oven service, or do you have dozens of available ovens stored in an oven repository where oven is just another domain entity? In #2, the oven is part of the domain. The way I tend to do domain modeling, most nouns are domain entities, unless you are 100% sure that there is exactly one of the thing.
But something does happen to pizza when it is baked.
interface ICanBeBaked {
int BakeMinutes { get; }
int BakeTemp { get; }
void Bake();
}
class Pizza : ICanBeBaked {
int BakeMinutes { get { return 15; } }
int BakeTemp { get { return 425; } }
void Bake() {
// melt cheese!
this.isBaked = true;
}
}
class Oven {
void Bake(ICanBeBaked thingToBake) {
// set the temp, reserve this oven for the duration, etc.
thingToBake.Bake();
}
}
My "DAL" (more of a home-grown ORM, which is another topic) is really a couple of layers in itself; one abstraction that provides repository and some active record pattern support, and below that is the actual data access code.
We have a minimal business layer at this point, but the real reason is that it's thin is that there's way too much (legacy) business logic embedded in web page code-behinds. As that gets refactored, I expect the business layer to grow and grow and grow.
This is fairly standard layering. You don't say why you're unhappy with your current stack, but keep in mind that the core reason for doing this is separation of responsibilities. You might also want to take a look at concepts of Domain Driven Design; it provides lots of food for thought for organizing code around business policies and practices, rather than specifically software issues. It's a very useful analytical tool to have in your toolbox.

Save Me on a Business Object

I've commonly seen examples like this on business objects:
public void Save()
{
if(this.id > 0)
{
ThingyRepository.UpdateThingy(this);
}
else
{
int id = 0;
ThingyRepository.AddThingy(this, out id);
this.id = id;
}
}
So why here, on the business object? This seems like contextual or data related more so than business logic.
For example, a consumer of this object might go through something like this...
...Get form values from a web app...
Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
thingy.Save();
Or, something like this for an update...
... Get form values from a web app...
Thingy thingy = Thingy.GetThingyByID(Int32.Parse(Form["id"].Value));
Thingy.Name = Form["name"].Value;
Thingy.Save();
So why is this? Why not contain actual business logic such as calculations, business specific rules, etc., and avoid retrieval/persistence?
Using this approach, the code might look like this:
... Get form values from a web app...
Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
ThingyRepository.AddThingy(ref thingy, out id);
Or, something like this for an update...
... get form values from a web app ...
Thingy thingy = ThingyRepository.GetThingyByID(Int32.Parse(Form["id"].Value));
thingy.Name = Form["Name"].Value;
ThingyRepository.UpdateThingy(ref thingy);
In both of these examples, the consumer, who knows best what is being done to the object, calls the repository and either requests an ADD or an UPDATE. The object remains DUMB in that context, but still provides it's core business logic as pertains to itself, not how it is retrieved or persisted.
In short, I am not seeing the benefit of consolidating the GET and SAVE methods within the business object itself.
Should I just stop complaining and conform, or am I missing something?
This leads into the Active Record pattern (see P of EAA p. 160).
Personally I am not a fan. Tightly coupling business objects and persistence mechanisms so that changing the persistence mechanism requires a change in the business object? Mixing data layer with domain layer? Violating the single responsibility principle? If my business object is Account then I have the instance method Account.Save but to find an account I have the static method Account.Find? Yucky.
That said, it has its uses. For small projects with objects that directly conform to the database schema and have simple domain logic and aren't concerned with ease of testing, refactoring, dependency injection, open/closed, separation of concerns, etc., it can be a fine choice.
Your domain objects should have no reference to persistance concerns.
Create a repository interface in the domain that will represent a persistance service, and implement it outside the domain (you can implement it in a separate assembly).
This way your aggregate root doesn't need to reference the repository (since it's an aggregate root, it should already have everyting it needs), and it will be free of any dependency or persistance concern. Hence easier to test, and domain focused.
While I have no understanding of DDD, it makes sense to have 1 method (which will do UPSERT. Insert if record doesn't exist, Update otherwise).
User of the class can act dumb and call Save on an existing record and Update on a new record.
Having one point of action is much clearer.
EDIT: The decision of whether to do an INSERT or UPDATE is better left to the repository. User can call Repository.Save(....), which can result in a new record (if record is not already in DB) or an update.
If you don't like their approach make your own. Personally Save() instance methods on business objects smell really good to me. One less class name I need to remember. However, I don't have a problem with a factory save but I don't see why it would be so difficult to have both. IE
class myObject
{
public Save()
{
myObjFactory.Save(this);
}
}
...
class myObjectFactory
{
public void Save(myObject obj)
{
// Upsert myObject
}
}

Categories

Resources