Giter VIP home page Giter VIP logo

dddinaction's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dddinaction's Issues

Validation?

Hi @vkhorikov,

Is there a reason you didn't address business rules in the domain and UI validation?

Thanks,

Karl

FluentAssertions 5.x has different syntax for ShouldThrow

The tests using ShouldThrow should be changed to the syntax below if you use a later version of FluentAssertions. I'm using 5.10.2

` public void Substract_more_then_exists()
{
Money money1 = new Money(0,1,0,0,0,0);
Money money2 = new Money(1,0,0,0,0,0);

        Action action = () =>
        {
            Money money = money1 - money2;
        };

        action.Should().Throw<InvalidOperationException>();

    }`

Snack repository and transactional consistency

Hey Vlad,

I am trying to learn DDD and your courses have helped me a lot. So, as far as I understand, an aggregate is a cluster of related objects that forms a boundary inside which transactional consistency is enforced. So, when fetching an aggregate using a repository from the database you should only fetch the data related to the entities (and value objects) contained in that aggregate. In the case of snack machine bounded context, there are two aggregates (snack machine and snack). However, you only created and used a single repository and disabled lazy loading (since you were creating a new session each time) when fetching the snacks for the slots/snack piles. So I have the following questions:

  1. Why did we do that? Shouldn't we create a separate snackRepository instead and have only the snackIds in the snack-piles? Then maybe use a snackRepository to fetch all the snacks by their IDs in our application services?

  2. Even if we used lazy loading, aren't we violating the rule about transactional consistency when loading the data of a different aggregate? What if we referenced multiple aggregates?

Note: I have read your article: https://enterprisecraftsmanship.com/posts/link-to-an-aggregate-reference-or-id/ and the comments.

Amazing course! As I am a java developer I tried to "translate" it in java (as a REST API using spring boot and hibernate). Here is the link to my repo in case you want to check it out: https://github.com/kosletr/DDD-In-Practice-In-Java

Repository is not repository

Hello,

I saw your code but I think repository is not a repository because you implement it as generic type. So it means each derived type will have Get/Save methods. When Save method is divided into Insert and Update and Remove method will be added there is class which implements CRUD operation above table. When you have class for CRUD operation it is more Table Gateway pattern than Repository pattern.
There is some differences between TableGtw and Repository pattern. Important thing in DDD (domain model more exactly) is that domain model works with entities aggregates. It means I have entity Invoice and it have many Items. Domain model works with root entity which is Invoice. Important is that nobody can change Invoice Item directly but Item are encapsulated inside Invoice entity and each change can be done by Invoice entity only - not from outside Invoice entity.
It means Invoice entity should be loaded with Items together. So Repository pattern can provide access to whole aggregate for Invoice entity. Instead of TableGtw pattern provides access to one table in database which means one entity - Invoice is loaded by InvoiceTableGtw and Items are loaded by InvoiceItemTableGtw. Exception could be value object which can be stored in same table as entity.
Repository pattern can provide some logic to check if entity is consistent and valid. It means it can check if price on Invoice entity is equal sum of price on items.
Repository is created only for root entities, not for entities inside aggregate.
Repository is not responsible for saving data to data store, it has not Save method.

I think it is very important to think in aggregates and each entity/value object is encapsulate inside aggregate and can be accessed and changed only by root entity - not directly outside of aggregate. It is difference to Table Module business pattern or Transaction Script.

There is difference between domain model and domain driven design (DDD) which is confused often. DDD is whole methodology how to distil bounded contexts, how to establish communication between contexts and other systems, what is core/support/generic domain, ... Domain model is more implementation technique which can take more complex business by model. Model can by created by Model Driven Design methodology but when we use DDD we create model for each context instead of whole system in case of Model Drive Design.
I saw some projects where people said we use DDD because we have entities, repositories and we have many apis. Ok and what are your bounded context? No, we don't have bounded context we have more apis and it is DDD. You don't have value objects. Each object has identity - primary key in database. Ok, but it is not business identity. Your entity has not any behavior it is POCO object - it is not domain model, it can be anemic domain model or another business pattern but not rich domain model. Each entity is 1:1 with database table and it is loaded by generic repository. Generic repository is TableGtw pattern. You don't have any domain service. We have services. Ok, but it is in application layer and these services hold use cases but domain service hold business case.

In DDD can be used any business pattern (domain model, transaction script or table module). DDD doesn't say which pattern or technology should be used. Each context can be implemented by different approach. DDD doesn't say nothing about code.

EventListener Class has misnamed method.

In order to compile;
This line -> aggregateRoot.ClearDomainEvents();
Needs to be changed to -> aggregateRoot.ClearEvents();

Note: I see in later versions of Khorikov's DDD classes there are a few method name changes and filename changes. for example -> IHandler.cs is renamed to IDomainEventHandler.

nHibernate 5.x does not have IPostInsertEvenListener

Hello, first ever issue I've raised on github. Hope I am doing right. This is more of a note than anything. One has to ensure you are downgraded to nHibernate 4.x to compile this. There are changes in nHibernate5.x that prevent compilation. Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.