S#arp Architecture: Where to put this domain logic - c#

re: S#arp Architecture
A bit of a noob question about where to put certain sorts of domain logic with S#arp. OK, so imagine this domain rule:
When asking for a specific chat room by name, return the room if it already exists, or else create a new one with that name and return it.
Is this Domain Logic? In which case, how do I implement it in my Entity object (as I seem to need access to the Repository to do it)
Is this Controller Logic? In which case I guess I stick it in the MVC controller, easy enough.
Is this Data Access Logic? In which case I build it into the Repository object and the Contoller calls it. Again, easy enough.
I reckon this is Domain Logic, but then I'm not sure how to built it into my Entity. As Entities dont seem to access to Repositories (or am I missing something?).

From the way you've described it, I'd say this would best go in the Application Services layer. (the Tasks layer in the WhoCanHelpMe? example project). For me this is application logic rather than domain logic.
For the other options:
Sharp is designed intentionally so that Entities don't access the Repositories. (You'll find quite a lot of articles around on why Entities should be persistence-ignorant.)
In general the controllers aren't really meant to contain any business logic directly - for readability, testability, etc. (Personally I'm comfortable putting logic in there initially and then refactoring it out.)
One reason I'd be uncomfortable putting the logic directly in a repository is clarity. If you have methods on IChatRoomRepository:
ChatRoom GetRoomByName (string name);
ChatRoom GetRoomById (int id);
typically GetRoomById would return null if there is no room for the given id, so it's not too obvious that the first method will silently create (and presumably persist?) a room if you don't already have one.
More conceptually, from DDD Quickly (p56):
We should not mix a Repository with a Factory. The Factory should create new
objects, while the Repository should find already created objects. When a
new object is to be added to the Repository, it should be created first
using the Factory, and then it should be given to the Repository
which would suggest that if you're trying to implement the repository pattern, the creation of a new chat room should happen outside the repository.

Related

Where should I put query logic related to filtering data by role user in DDD architecture

I am following DDD architecture for my app. I have App layer, domain layer and data access layer(repository).
Let say I would have 3 roles in my app: admin, supervisor, agency. Every role should access data that assigned to itself.
So the problem is, should i put query logic in order to filter data by role in Repository like
var query = dataContext.Order.Where(...);
if(userRole = "admin")
query =.... filter by admin
If(usrRole = "supervisor")
query =....
return query.ToList();
I think the logic related to business logic and should put in domain layer. But I havent clear this one.
Can you guys clear this out for me?
The best explanation I've read so far is the one from Patterns, Principles And Practices Of Domain-driven Design, published by Wrox. The image below resembles the core idea.
All dependencies point inward, so the domain model depends on nothing else, and knows about nothing else. Therein it's pure, and can focus on what matters, the language of the domain.
The application layer (containing the application services) exposes an API of use cases and orchestrates the requests with the involved domain services. Therefore, the code in application services is procedural, while the code in the domain model is usually much richer. That is, if the domain is complex enough to warrant it.
But I digress, to answer your question, the application layer exposes interfaces for the infrastructure to implement (eg repository pattern). It's also the application layer that knows how to query the data (through the use of this interface), and filter it based on the role.
The domain model should only receive the filtered collection, and focus only on one thing, processing the data.
For completeness, DDD allows many architectures, as long as the domain has no dependencies. Though I find it easiest to grasp, thinking about it this way.
Repositories represent collections of aggregate roots. So when you want to retrieve some aggregate or a list of aggregates that you need to perform business operations on the repository is the place to go.
In your case I imagine you have some kind of User aggregate and I can think of methods like the following on your repository:
findById(UserId id)
findByRole(UserRole role)
While findById() will only return one aggregate and findByRole() returns a list of aggregates.
Always keep in mind to only return full aggregate objects from the corresponding repository and define the repository interface in the domain layer while putting the repository implementation into the infrastructure layer.
There might be reasons not to return a full aggregate from a repository like creating summaries or calculating just an amount of, e.g. the number of users with specific criteria. But keep in mind to only return immutable objects in that case which are meant to be read only. But these kind of information should be relevant for performing business operations only in most cases.

Is this the Clean Data pattern?

What is the name of the pattern in which every piece of data that the presentation layer gets and saves is as simple as possible with no ef context info attached?
eg.
CustomerManager manager = new CustomerManager();
Customer customer = manager.GetCustomerByEmail(string emailAddress);
DoSomething(customer);
manager.Save(customer);
And is this recommended for use in MVC? I see so many examples where controllers and view models are using ef contexts. It strikes me as bad practice.
PS. My reference to the "Clean Data" pattern was just my best guess and not a reference to an actual pattern.
I've never come across the "Clean Data" pattern.. but this looks more like the Active Record Pattern.
Generally when applying this pattern, your domain objects have Insert(), Update() and Delete() methods on them.
Its not often you see this approach these days. People tend to prefer keeping the persistence logic and business logic decoupled.. whereas this approach leads you down the path of them being very intertwined. This makes it harder to test and the codebase becomes resistant to changes.
The named pattern that I tend to use is the "repository" pattern, where the repository encapsulates the implementation details of how the data access layer is used. That way you can switch from EF (or whatever) without your controller-layer code needing to know about it.
http://martinfowler.com/eaaCatalog/repository.html

Pattern for retrieving complex object graphs with Repository Pattern with Entity Framework

We have an ASP.NET MVC site that uses Entity Framework abstractions with Repository and UnitOfWork patterns. What I'm wondering is how others have implemented navigation of complex object graphs with these patterns. Let me give an example from one of our controllers:
var model = new EligibilityViewModel
{
Country = person.Pathway.Country.Name,
Pathway = person.Pathway.Name,
Answers = person.Answers.ToList(),
ScoreResult = new ScoreResult(person.Score.Value),
DpaText = person.Pathway.Country.Legal.DPA.Description,
DpaQuestions = person.Pathway.Country.Legal.DPA.Questions,
Terms = person.Pathway.Country.Legal.Terms,
HowHearAboutUsOptions = person.Pathway.Referrers
};
It's a registration process and pretty much everything hangs off the POCO class Person. In this case we're caching the person through the registration process. I've now started implementing the latter part of the registration process which requires access to data deeper in the object graph. Specifically DPA data which hangs off Legal inside Country.
The code above is just mapping out the model information into a simpler format for the ViewModel. My question is do you consider this fairly deep navigation of the graph good practice or would you abstract out the retrieval of the objects further down the graph into repositories?
In my opinion, the important question here is - have you disabled LazyLoading?
If you haven't done anything, then it's on by default.
So when you do Person.Pathway.Country, you will be invoking another call to the database server (unless you're doing eager loading, which i'll speak about in a moment). Given you're using the Repository pattern - this is a big no-no. Controllers should not cause direct calls to the database server.
Once a C ontroller has received the information from the M odel, it should be ready to do projection (if necessary), and pass onto the V iew, not go back to the M odel.
This is why in our implementation (we also use repository, ef4, and unit of work), we disable Lazy Loading, and allow the pass through of the navigational properties via our service layer (a series of "Include" statements, made sweeter by enumerations and extension methods).
We then eager-load these properties as the Controllers require them. But the important thing is, the Controller must explicitly request them.
Which basically tells the UI - "Hey, you're only getting the core information about this entity. If you want anything else, ask for it".
We also have a Service Layer mediating between the controllers and the repository (our repositories return IQueryable<T>). This allows the repository to get out of the business of handling complex associations. The eager loading is done at the service layer (as well as things like paging).
The benefit of the service layer is simple - more loose coupling. The Repository handles only Add, Remove, Find (which returns IQueryable), Unit of Work handles "newing" of DC's, and Commiting of changes, Service layer handles materialization of entities into concrete collections.
It's a nice, 1-1 stack-like approach:
personService.FindSingle(1, "Addresses") // Controller calls service
|
--- Person FindSingle(int id, string[] includes) // Service Interface
|
--- return personRepository.Find().WithIncludes(includes).WithId(id); // Service calls Repository, adds on "filter" extension methods
|
--- IQueryable<T> Find() // Repository
|
-- return db.Persons; // return's IQueryable of Persons (deferred exec)
We haven't got up to the MVC layer yet (we're doing TDD), but a service layer could be another place you could hydrate the core entities into ViewModels. And again - it would be up to the controller to decide how much information it wishes.
Again, it's all about loose coupling. Your controllers should be as simplistic as possible, and not have to worry about complex associations.
In terms of how many Repositories, this is a highly debated topic. Some like to have one per entity (overkill if you ask me), some like to group based on functionality (makes sense in terms of functionality, easier to work with), however we have one per aggregate root.
I can only guess on your Model that "Person" should be the only aggregate root i can see.
Therefore, it doesn't make much sense having another repository to handle "Pathways", when a pathway is always associated with a particular "Person". The Person repository should handle this.
Again - maybe if you screencapped your EDMX, we could give you more tips.
This answer might be extending out a little too far based on the scope of the question, but thought i'd give an in-depth answer, as we are dealing with this exact scenario right now.
HTH.
It depends on how much of the information you're using at any one time.
For example, if you just want to get the country name for a person (person.Pathway.Country.Name) what is the point in hydrating all of the other objects from the database?
When I only need a small part of the data I tend to just pull out what I'm going to use. In other words I will project into an anonymous type (or a specially made concrete type if I must have one).
It's not a good idea to pull out an entire object and everything related to that object every time you want to access some properties. What if you're doing this once every postback, or even multiple times? By doing this you might be making life easier in the short term at the cost of you're making your application less scalable long term.
As I stated at the start though, there isn't a one size fits all rule for this, but I'd say it's rare that you need to hydrate that much information.

Services and Repositories in DDD (C#)

How do Services and Repositories relate to each other in DDD? I mean, I've been reading up on DDD for the past 2 days and everywhere I go, there's always a Service layer and there's always a Repository layer. How do these differentiate or compliment each other?
From what I've read, isn't the Repository the layer responsible for delegating interactions between the application and the data?
So, what's the need for the Service layer if it has to implement the Repository to interact with the data anyway even though the Repository probably already implements the methods needed to do so?
I'd appreciate some enlightenment on the subject.
P.S. Don't know if this will help any, but I'm working with an ASP.NET MVC 2 application in which I'm trying to implement the Repository pattern. I just finished implementing the Dependency Injection pattern (for the first time ever)...
UPDATE
Okay, with so many answers, I think I understand what the difference is. So, to review (correct me if I'm wrong):
A Repository layer interacts only with a single object out of the database or the ORM, IEmployeeRepository -> Employee.
A Service layer encapsulates more complex functionality on objects returned from Repositories, either one or multiple.
So, then I have a sub question. Is it considered bad practice to create abstract objects to be sent to my views? For example an AEmployee (A for abstract because to me I means interface) which contains properties from Employee and X or X?
Actually, one more subquestion. If a Service layer can be considered "tuned" for an application does it need to be implemented with an interface?
The Service will use a Repository to retrieve an Entity and then call methods on it (the Entity) to perform the Command/task.
True, a repository works with data (ie. SQL, Webservice etc.) but that's the only job. CRUD operations, nothing more. There is no place for stored procedure based busines logic.
The service (or business logic layer) provides the functionality. How to fullfill a business request (ie. calculate salary), what you have to do.
Oh, and this is a really nice DDD book:
http://www.infoq.com/minibooks/domain-driven-design-quickly
As a concrete example a Shopping Cart application might have the following services:
ShoppingCartService - manages a cart of items with add/remove/update support etc.
OrderService - take a cart, converts it to an order and handles the payment process etc.
each of these services needs to talk a "data source" for CRUD operations. This is where the Repository pattern comes in handy as it abstracts the loading and saving of data to and from the data source be it a database, web service or even in-memory cache.
When you want to create a quick prototype of your application without having to deal with database setup, schema, stored procedures, permissions, etc. you can create a cache or fake repository in a matter of minutes.
For the example above your prototype might start off with the following:
FakeCustomerRepository
FakeAddressRepository
FakeCartRepository
FakeCartLineItemRepository
FakeOrderRepository
FakeOrderLineItemRepository
once your prototype is ready to evolve to the next level you can implement these against a real database:
SQLCustomerRepository
SQLAddressRepository
SQLCartRepository
SQLCartLineItemRepository
SQLOrderRepository
SQLOrderLineItemRepository
From what I can remember, the repository is the final class before the data. The service class can act on data retrieved from the repository. The repository is really just meant to get data to somebody else to do the work. The service layer can provide things such as business logic that all data must pass through. It could also provide for a translation between the application logic and the data layer. But again, this is just what I can remember.
There's no golden standard that defines a service or a repository. In my applications a repository is (as you say) an interface into a database. A service has full access to a repository - but the service exposes a subset of functionality to its consumers.
Think of the repository as more low level. The repository has to expose many ways of accessing the underlying database. A service might combine calls to a repository with other code that only makes sense at a code level (i.e. not in the database), such as access to other state in the application, or validation/business logic that can't easily be applied in a database.

Access Repository through Service or directly?

is itIa good coding standard to allow ASP.NET MVC controller actions to access a repository directly (even though a service layer is present for the heavy lifting, e.g. LoginService.Authorize() ) to retrieve, add, or update data? Or should everything go through the service, and from there to the repository?
For smaller applications/webs, i tend not to use service layer, because it just maps Repositories methods 1:1, and I loose KISS. But in the end, it depends on business model; repository abstracts db access, and services encapsulates logic.
It's better to go through the service layer (depending on how you've implemented it though), because that's the point of it - to be a single access point, thus any business-specific things you do there, are represented and implemented across all callers.
It really depends on the complexity. If you're dealing with any transcation scoping, I'd definitely decouple that away from the controller into your service layer.
In my opinion it will depends on your design/architecture. What's the purpose of a repository ? Do CRUD operations (Create, Read, Update and Delete).
If you're using the anemic domain models in a classic three-tiers architecture all logic applied to the models are made in the services.
In this case the choice is obvious : You shouldn't call the repository directly.
Why ? Since your models are silly and the logic is in the services you could create invalid models. If you can call the repository you could create/update an invalid model in database. If you call the services it should be able to correct or fill your model before create/update it.
If you're using a rich domain model in an onion architecture it's different. Since your models are supposed to be always valid (when you create one from the constructor or from the factory all validations has been performed and when you update one it's the same thing) you can without any problem call directly the repository.
In this context all the logic is in the models directly and the services are just used to stored the logic that doesn't belong to one model specificly.
Now the question is not "how to use repository" but "what design/architecture do I need ?" and the first question will be answered :-)

Categories

Resources