My project structure is Client <=> Web API <=> BL <=> DAL (Repository) <=> DB.
Does it make sense that one API will know many BLs? Meaning that in one API method it will call to X_BL and in another method, at the same API class it will call to Y_BL? If it makes sense, can you please provide an example?
Or is it always should be 1:1 relation, so that each API controller will call to its BL, for example: CustomersAPI will always call to CustomersBL, and ProductsAPI will always call to ProductsBL.
In my opinion the answer it's depends, there are many questions that need to be answered first
What do you make a API for ?
Do you have to follow the architectural design patterns owned by API users (E.g. MobileApp, WebApp) ?
Or just want to make an API that only provides data in like you said, 1:1 relation, so the other app must follow the architectural design patterns you make ?
Where you focus on processing data, client side or server side ?
What are the limits of the work scope of the API and its users ?
In my experiences, if you want to make a scalable REST API, your controller must be able to access any BLL (Business Logic Layer) when it's needed. BLL = BL (in your case)
E.g. :
http://localhost/customers/15
The customers controller only needs 1 BLL (CustomerBLL) to find a customer with ID 15 then return the result. Like you said, 1:1 relation.
In the other case, you'll need more than 1 BLL.
E.g. :
http://localhost/customers/15/products
The customers controller needs another BLL (ProductsBLL) to find any products that related to customers with ID 15 then return the result.
It absolutely makes sense, APIs often require multiple pieces of business logic to solve a particular problem. For example, your CustomersAPI may talk to a CustomersBL, but also talk to a UsersBL to get the authorization context (which customers can be returned), or to a CRM BL when actions are performed.
Related
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.
I want to build server for Point Of Sales which is going to be on top of Web Api asp.net
My plan is to have one controller for bills.
For handling bills from web-api post to sql server I am planing to use micro ORM PetaPoco.
One bill is going to be written in database at three tables.
PetaPoco pushing me to have three "pocos" for-each table one.
I want to write these three pocos to database inside transaction.
How I shod design my controller and classes to looks nice also work nice.
Should I ?
Make my controller accept three (3) classes for for parameters, Is this possible at asp.net web api at all ? Can I deserialize from one request three different classes ?
Make my controller accept one class, after that on server side from that class make three pocos which is going to be written to Database server ? Can someone post how wold looks like that class which is going to be split at three parts ?
Make my controller have three methods for posting separate data (bills-header, bills-payment, bills-articles) one by one ?
Perhaps it will be so hard in this case to have one transaction for three separate calls?
Any other approach ?
I would definitely go with option 2 - since your web client should be agnostic of the implementation details - i.e. whether you are persisting to one table or 3 tables shouldn't really matter to the client.
The controller or the service method would look like this (obviously the naming is not great - you'll have to modify it according to your domain lingo):
public void AddBill(BillDTO bill)
{
//Map the DTO to your entities
var bill1 = mapper1.Map(bill);
var bill2 = mapper2.Map(bill);
var bill3 = mapper3.Map(bill);
//Open the transaction
using (var scope = db.Transaction)
{
// Do transacted updates here
db.Save(bill1);
db.Save(bill2);
db.Save(bill3);
// Commit
scope.Complete();
}
}
You should read about DTO pattern, it would answer some of your questions:
1. WebAPI supports it.
2. That sounds like DTO, so it is a good solution, as you hide your persistence model from consumer.
3. There's no point to force consumer to make three calls, each call has own 'infrastructure' cost, so it is better have one infrastructure cost instead of one.
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.
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.
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 :-)