How to avoid circular dependency: DAL.DbContext.DbSet<BLL.Model> - c#

If DbContext is in the DAL then the generic type arguments of the DbSets cannot be the BLL classes (domain model). What are the best practice ways to separate these layers? An extra model in the DAL? Interfaces?

If you're doing DDD, I believe the repository (at least the interface for it) is part of your business / domain layer. Your implementation of the repository will be a separate assembly which would have to reference that business / domain layer. So your DAL knows about your business objects, but not the other way around. To do dependency injection, you'll probably have in your DAL layer something that configures your container to use Repository for your IRepository interface. If you need a unit of work patter, your interface would likely have to be part of the business layer as well. Again your implementation will be in your DAL and the DAL would configure the DI container appropriately. This is actually one of the things I dislike about the repository pattern, as you either need to ensure your users of your interface correctly manage the IUnitOfWork, or you need something to wrap the repository which does so.
In a traditional n-layer architecture, things are a bit different. In that case your business layer can talk to the DAL, and I've normally built the DAL to have DTOs which represent a row of data in the database. The business layer will then use these DTOs to hydrate the business objects (or if you're using something like CSLA.Net, the business objects know how to hydrate themselves).
Either way there shouldn't be a situation where you end up with a circular reference.

I usually consider the domain model as a separate layer.
If we look at the classic MVC paradaigm, then the model is used by both the View and the Controller.
No reason why it shouldn't be used by the DAL as well.
The Model, however, will not reference the DAL; all operations against the data store will be done by the controller.
So the general flow of things would be-
user interacts with the View
View invokes a method on the Controller
Controller uses the DAL to retrieve Model objects
Controller invokes methods on Model objects, saves them (using DAL) if necessary, and returns an answer to the View

Your BLL or Domain Layer should not worry about data access technical details, BLL shold be technology independent. If you want to stick with Entity framework you should generate POCO entities and move them to seperate layer, this way you can avoid circualr references.

Related

DDD: Should Persistence Logic belong to Infrastructure Layer?

Well my application follows DDD design principles. It is an ASP.NET MVC application with the MVC web application being the presentation layer(I moved controllers to application layer though). It also has Application Layer that is primarily application services, use cases, etc. Above the Application Layer is the Domain Layer where Domain Models reside. Then there is Infrastructure Layer, which sits on top of everything else, and is supposed to be dependent on no other layers.
But there is one problem I noticed, that if Persistence Logic goes into Infrastructure Layer as the DDD books suggest, the Infrastructure Layer will have dependency to Domain Layer. The Repositories, for instances, need to know the types of Domain Models(Entities) to create, with this knowledge they become dependent on Domain Layer. The original DDD principles however, suggest that Infrastructure Layer should have absolutely no dependency for anything.
So now I am confused, should Persistence Logic really, belong to the Infrastructure Layer? If so, it makes Infrastructure Layer dependent on Domain Layer. If not, then where should it be? Application Layer? Or maybe a separate layer between Application Layer and Domain Layer(as application services use repositories, repositories use domain models). What do you think?
Types of Dependency
I think an important concept that might assist here is to distinguish types of dependency - specifically, a layer or component can be dependent on another layer because either:
is defined in terms of concepts defined in that layer, or
it uses the other layer - by delegating to that layer (aka calling methods on services in that layer)
Or both the above
Inversion of Control and Dependency Injection make this distinction even more important. They guide that we should depend on abstractions rather than concretions.
This means that, for example, the domain layer can define and depend on an abstraction of a repository - e.g. an IEntityRepository interface.
However, the implementation (concretion) is then implemented in the infrastructure layer.
When the application layer wants to call on the repository, it depends on the abstraction (the interface), and the inversion of control system (IoC Container) supplies it with an implementation from the infrastructure layer.
In this case, the infrastructure layer depends on the domain layer - but only in order to know about the interface it is implementing, but it does NOT depend on any other layer in order to delegate to it - it is the last layer in the call stack.
This concept resolves the conflict you were concerned about, because the infrastructure layer doesn't depend on anything else to carry out it's function.
Onion Architecture
Once you start to incorporate IoC concepts into thinking about your architecture, a model that can become very helpful is the onion architecture pattern. In this view, we retain the layered approach, but rather than thinking of it as a stack, think of it as a layered onion, with the Domain in the centre and the interactions with everything outside the application on the edges.
The original DDD books didn't specifically reference this, but it has become a very common pattern for implementing DDD systems.
It is also known as the Ports and Adaptor pattern, or the Hexagonal Architecture.
The idea is that it models dependencies in terms of 'knowing about' in terms of an onion - outer layers know about inner layers but inner layers don't know about outer layers.
But it models delegation of application flow in terms of movement across the onion - from one side of the onion to the other.
To be more specific:
The outer layer (also known as a 'primary adaptor') is where the request enters the system. The adaptor has the responsibility for handling a specific API presentation (e.g. a REST api) and transforming it into a request to the Application services layer - the next layer in. This is often represented as the top-left of the onion.
The Application services layer represents a 'use case' of the application. Typically a method would use a repository interface to retrieve an instance of an aggregate, then delegate to methods on the aggregate root to execute the business logic that involves changing the state of the aggregate as required for the use case. The application services layer, then uses another interface to ask the infrastructure layer to 'save' changes (often using a unit of work abstraction)
Here we have the application layer delegating control flow to an 'outer layer' of the onion (otherwise known as 'secondary adaptors'). This is often represented as the bottom-right of the onion, and is analogous to the 'infrastructure layer' in your description.
And this is where IoC comes in. Because we have an inner layer delegating to an outer layer, it is only possible because the outer layer has implemented an interface defined in an inner layer (which it can do because it knows about the inner layer). However, the IoC container injects the actual concrete implementation which effectively permits the inner layer to delegate control to the outer layer without being dependent on it.
In this conceptualisation, the request has flowed from the top left to the bottom right without the inner layers knowing anything about the outer layers.
There are 2 options here
1) Work with DAO objects. then the infrastructure layer only needs to know about those DAO objects. Especially if you use Entity framework or something similar then this isn't a bad strategy to follow. You do gain some overhead from mapping but you can use an Automapper for that.
2) live with the fact that the infrastructure knows about your DDD model. But since everything in DDD revolves around your domain model this isn't that bad of a tradeoff. (Especially if your domain model is very well understood and thus doesn't change radically). Be very careful though not to let your domain model be influenced because of database design. It should always be the database who follows, never the domain model where you don't make a certain change because it's hard to migrate in the database.
Persistence Logic usually belongs in the Infrastructure Layer, which is in the outer layer of the onion, and since the outer layers of onions depend on the inner layers, and the Domain Layer is in the center, then yes the Infrastructure Layer depends on the Domain Layer.
In DDD scope, the Persistence Logic should belong to Infrastrure Layer, as detailed persistence implementations are not the concern of Domain Layer.
However, as we think of the architecture of our projects differently, Infrasture Layer could either be dependent on Domain Layer or being depended on by it.
In a traditional layered architecture,
A linear dependency is suggested all the way passed from Presentation Layer, via Application Layer, Domain Layer to Infrastructure Layer.
In this case Infrasture Layer is deemed as an upperstream where both the interfaces and implementations of Persistence Logic are defined.
Domain Layer, as a downstream user, would follow the interface provided by Infrastructure Layer to fetch the entities, convert into domain objects, and then do the domain logic.
Typical codes in java:
// package com.xxxx.product.application
class ProductOrderApp {
private ProductRepository repository;
void orderOneProduct(String userCode, String productCode) {
ProductEntity enitity = repository.getOneByProductCode(productCode);
// 1. convert ProductEntity to Product Object
// 2. pass Product Object to Domain layer to do some logic
...
}
}
// package com.xxxx.product.domain
class Product { ... }
// package com.xxxx.product.infrastructure
interface ProductRepository {
// does not depend on any domain concepts
ProductEntity getOneByProductCode(String code);
}
class ProductRepositoryImpl implements ProductRepository {
#Override
ProductEntity getOneByProductCode(String code) {
ProductEntity entity = ... // get entity from some database
return entity;
}
}
In an onion architecture(as well explained in top answers),
Domain Layer is considered the upperstream, and all other downstream layers should follow the interfaces provided by Domain Layer.
Thus Infrastrure Layer depends on Domain Layer as in it implements the interfaces defined by Domain Layer. Domain Layer does not depend on Infrastructure Layer.
Typical codes in java:
// package com.xxxx.product.domain
class Product { ... }
interface ProductRepository {
// other Domain Logic can easily call this method as it uses Domain Objects for interection
Product getOneByProductCode(ProductCode code);
}
// package com.xxxx.product.infrastructure
class ProductRepositoryImpl implements ProductRepository {
#Override
Product getOneByProductCode(ProductCode code) {
ProductEntity entity = ... // get entity from some database
// persistence logic knows domain objects and do the convertion here
return convertToProduct(entity); // convert to domain objects
}
}

Do I need to Separate Business Objects and Business Logic? Asp.net MVC with Repository Pattern in C#

I'm having trouble finding an answer to this. Basically, right now I have these layers:
Data Access Layer (where my repositories are). It has Namespace Hello.Data
Business Layer (where my business objects are). It has Namespace Hello.Business
My repositories will return business objects. For example, GetCustomer will return Customer.
However, in my business layer, I also want to add logic that will use the repository to add/update/delete records, so I can reuse those methods in my MVC controllers. This doesn't work though, since I can't have my Data Access Layer reference my Business Layer and also have my Business Layer reference my Data Access Layer. (It creates a circular reference that is not allowed).
What do you guys think is the best solution? Should I put my Business Logic into it's own project?
So instead of:
Hello.Data
Hello.Business
I'll have:
Hello.Data
Hello.Business
Hello.BusinessLogic
Or am I thinking about this all wrong? Thanks!
Why would you separate business logic from business models? The logic should be in the models.
The business logic layer shouldn't have to reference anything, aside from maybe small common utility libraries. Basically, it should have no dependencies on infrastructure concerns (like application technologies, database technologies, etc.). It should contain just business logic.
All other layers should reference the business logic layer.
This doesn't work though, since I can't have my Data Access Layer reference my Business Layer and also have my Business Layer reference my Data Access Layer.
Correct! The mistake in this design is that the business logic layer references the data access layer at all. It shouldn't.
It should, however, contain interfaces for data access (and other infrastructure concerns) which are implemented by the data access layer. The business logic layer only needs to know about the interfaces, it doesn't know or care what implements those interfaces.
A dependency injection container would then be used to connect implementations to interfaces.
The application layer references the dependency injection layer to initialize it and pass the container (which itself implements a generic business logic interface) to the business logic layer.
The dependency injection layer references the business logic layer to know about the interfaces and references the data access (and other infrastructure) layer to know about the implementations.
The data access (and other infrastructure) layer references the business logic layer to know about the interfaces to implement.
The business logic layer doesn't reference anything. It requires a configured dependency injection container and uses that container to get implementations for interfaces.

Should Business Logic Layer access the DB/Data Access Layer?

I'm a bit confused about the relationship a BLL and DAL has. Should the BLL encapsulate the DAL via dependancy injection? Or should the BLL only act on domain objects and the DAL save/update seperately?
For example imagine (in a typical MVC app) a Cancel Order function that requires you to update the order and update the stock. Would the following be how my action would look?
public ActionResult CancelOrder (Guid orderId) {
Order order = orderRepository.Get(orderId);
StockItem stockItem = stockRepository.Get(order.StockItemId);
_orderService.CancelOrder(order, stockItem);
orderRepository.Update(order);
orderRepository.Update(stock);
Return View();
}
Or should it be more like the following?
public ActionResult CancelOrder (Guid orderId) {
_orderService.CancelOrder(orderId);
Return View();
}
(within OrderService)
public void CancelOrder(Guid orderId) {
Order order = orderRepository.Get(orderId);
StockItem stockItem = stockRepository.Get(order.StockItemId);
order.Cancelled = true;
stockItem.AmountInStock = stockItem.AmountInStock + order.Amount;
orderRepository.Update(order);
orderRepository.Update(stock);
}
With this option everything would then be handled by the BLL including data access. The repositories would be injected in to avoid tight coupling. Any entity retrieval would then take the form of _orderService.GetOrder(orderId); as apposed to going straight to the repository.
Excuse the crudeness of the examples as I don't have a lot of time. Does any of what I've written even remotely make sense or am I off in the wilderness?
Definitely not the first option, which embeds your business logic in the controller. The problem is not that the controller accesses data objects per se, but that a procedure dictated by business rules has to be followed. This procedure has no place in the controller.
So you should either go with the second option, or possibly make Cancel a method of Order. If you have already written similar code just go with consistency.
Think of separation of concerns, Controller is from MVC pattern which is PRESENTATION pattern, so controller should contains presentation logic support presentation layer, not business logic.
It is agreed that business logic should be in domain entities, but there are also some APPLICATION logic which plays a roles as coordinators between repositories, that is why the service layer is downed on the road.
Therefore, option 2 should be in your way.
You're really asking 2 questions here :
What should be in the Controller vs in the business layer ?
=> I tend to think the code in your first snippet is the right level of responsibility for an Application layer service (and consequently for a Controller if you admit that the two can be likened, which there's a lot of discussion about these times). Getting the Order from the repository and saving it after the cancel operation hardly seems like pure business logic. It has more to do with the surrounding transaction/unit of work and the plumbing of your use case.
I'd just change one thing - try to save changes to all entities affected by your transaction in one go. If you have to manually update every entity that could possibly be changed at the end of an operation, it's going to be a big pain and will pollute the controllers unnecessarily. Create a unit of work system (or use an existing implementation) that will persist all changes at once and remove all the Update() methods in your repositories.
Other than that, as Jon suggests, I also believe that a rich Order domain object containing the Cancel() method would be preferrable to a service - but this is another debate.
What kind of relationship should there be between BLL and DAL ?
=> The BLL shouldn't be tightly coupled to the DAL and as the centermost layer, it isn't supposed to reference outer layers directly. This way you can easily reuse your BLL in another application, with another DAL, etc.
However, there are times when some business objects need direct access to other objects they don't already have a reference to, which basically means getting them from the database. In other words, some operations in the BLL need to talk to the repositories. Therefore, I always place repository interfaces in the BLL, but their implementations reside in the DAL, and they are injected into the BLL at runtime.
As a result, the BLL is only loosely coupled to the DAL. It remains persistence ignorant in that it manipulates only facades (repositories) which look like neutral collections of objects and stays oblivious of how data is stored, hydrated, and so on.
BLL should act on the business objects that you have created for your application. It, ideally, should not be aware of database and related operations. If you are looking to keep things loosely coupled, make use of dependency injection to call methods from your DAL.

Enterprise Design Pattern Question

Something on my mind about structuring a system at a high level.
Let's say you have a system with the following layers:
UI
Service Layer
Domain Model
Data Access
The service layer is used to populate a graph of objects in the domain model. In an attempt to avoid coupling, the domain model will be not be persistence aware and will not have any dependencies on any data access layer.
However, using this approach how would one object in the domain model be able to call other objects without being able to load them with persistence, thus coupling everything together - which I'd be trying to avoid.
e.g. an Order Object would need to check an Inventory object and would obviously need to tell the Inventory object to load in some way, or populate it somehow.
Any thoughts?
You could inject any dependencies from the service layer, including populated object graphs.
I would also add that a repository can be a dependency - if you have declared an interface for the repository, you can code to it without adding any coupling.
One way of doing this is to have a mapping layer between the Data Layer and the domain model.
Have a look at the mapping, repository and facade patterns.
The basic idea is that on one side you have data access objects and on the other you have domain objects.
To decouple you have to: "Program to an 'interface', not an 'implementation'." (Gang of Four 1995:18)
Here are some links on the subject:
Gamma interview on patterns
Random blog article
Googling for "Program to an interface, not an implementation" will yield many useful resources.
Have the domain model layer define interfaces for the methods you'll need to call, and POCOs for the objects that need to be returned by those methods. The data layer can then implement those interfaces by pulling data out of your data store and mapping it into the domain model POCOs.
Any domain-level class that requires a particular data-access service can just depend on the interface via constructor arguments. Then you can leverage a dependency-injection framework to build the dependency graph and provide the correct implementations of your interfaces wherever they are required.
Before writing tons of code in order to separate everything you might want to ask yourself a few questions:
Is the Domain Model truly separate from the DAL? And yes, I'm serious and you should think about this because it is exceedingly rare for an RDBMS to actually be swapped out in favor of a different one for an existing project. Quite frankly it is much more common for the language the app was written in to be replaced than the database itself.
What exactly is this separation buying you? And, just as important, what are you losing? Separation of Concerns (SoC) is a nice term that is thrown about quite a bit. However, most people rarely understand why they are Concerned with the Separation to begin with.
I bring these up because more often than not applications can benefit from a tighter coupling to the underlying data model. Never mind that most ORM's almost enforce a tight coupling due to the nature of code generation. I've seen lot's of supposedly SoC projects come to a crash during testing because someone added a field to a table and the DAL wasn't regenerated... This kind of defeats the purpose, IMHO...
Another factor is where should the business logic live? No doubt there are strong arguments in favor of putting large swaths of BL in the actual database itself. At the same time there are cases where the BL needs to live in or very near your domain classes. With BL spread in such a way, can you truly separate these two items anyway? Even those who hate the idea of putting BL in a database will fall back on using identity keys and letting the DB enforce referential integrity, which is also business logic..
Without knowing more, I would suggest you consider flattening the Data Access and Domain Model layers. You could move to a "provider" or "factory" type architecture in which the service layer itself doesn't care about the underlying access, but the factory handles it all. Just some radical food for thought.
You should take a look at Martin Fowler's Repository and UnitOfWork patterns to use interfaces in your system
Until now I have seen that application can be well layered into three layers: Presentation-->Logic-->Data--and Entities (or Bussines Object). In the Logic Layer case you can use some pattern such as Transaction Script or Domain Model I'm supposing you're using this last. The domain model can use a Data Mapper for interacting with the data layer and create business objects, but you can also use a Table Module pattern.
All this patterns are described in Marttin's Fowler Patterns of Enterprise Application Architecture book. Personally I use Transaction Script because it is simplest than Domanin Model.
One solution is to make your Data Access layer subclass your domain entities (using Castle DynamicProxy, for example) and inject itself into the derived instances that it returns.
That way, your domain entity classes remain persistence-ignorant while the instances your applications use can still hit databases to lazy-load secondary data.
Having said that, this approach typically requires you to make a few concessions to your ORM's architecture, like marking certain methods virtual, adding otherwise unnecessary default constructors, etc..
Moreover, it's often unnecessary - especially for line-of-business applications that don't have onerous performance requirements, you can consider eagerly loading all the relevant data: just bring the inventory items up with the order.
I felt this was different enough from my previous answer, so here's a new one.
Another approach is to leverage the concept of Inversion of Control (IoC). Build an Interface that your Data Access layer implements. Each of the DAL methods should take a list of parameters and return a Data Table.
The service layer would instantiate the DAL through the interface and pass that reference to your Domain Model. The domain model would then make it's own calls into the DAL, using the interface methods, and decide when it needs to load child objects or whatever.
Something like:
interface IDBModel {
DataTable LoadUser(Int32 userId);
}
class MyDbModel : IDBModel {
DataTable LoadUser(Int32 userId) {
// make the appropriate DB calls here, return a data table
}
}
class User {
public User(IDBModel dbModel, Int32 userId) {
DataTable data = dbModel.LoadUser(userId);
// assign properties.. load any additional data as necessary
}
// You can do cool things like call User.Save()
// and have the object validate and save itself to the passed in
// datamodel. Makes for simpler coding.
}
class MyServiceLayer {
public User GetUser(Int32 userId) {
IDBModel model = new MyDbModel();
return new User(model, userId);
}
}
With this mechanism, you can actually swap out your db models on demand. For example, if you decide to support multiple databases then you can have code that is specific to a particular database vendors way of doing things and just have the service layer pick which one to use.
The domain objects themselves are responsible for loading their own data and you can keep any necessary business logic within the domain model. Another point is that the Domain Model doesn't have a direct dependency on the data layer, which preserves your mocking ability for independent testing of business logic.
Further, the DAL has no knowledge of the domain objects, so you can swap those out as necessary or even just test the DAL independently.

Abstracting the DataLayer (DAL) of a three-tier application

As continuation to my previous question, (see https://stackoverflow.com/questions/3737848/creating-a-loosely-coupled-scalable-software-architecture
Someone suggests to also Abstract the DAL like I abstracted the BLL from the Presentation Layer on my three tier project. Any suggestion on how to do this? Do I also need a factory between the BLL and the DAL? I need your input guys.. thanks.
Interesting - I'd put abstraction between the BL and DAL way before I'd do that for the presentation layer.
The approach used in your other question seems reasonable - why don't you just reuse that?
Yes you need a factory; but you can include this in a common class / assembly and have it just return a object, which you can then cast as it's returned - i.e: at the point in the BL where it's being called.
(for completeness:) using Activator.CreateInstance() (as you've used in your other question) is the right way to go.
For DAL I tend to use values stored in the config (as arguments to pass into the factory); it's not common to change the DAL implementation that often - so config works well for me.
Observe the Interface Segregation Principle (ISP) when designing the contractr / abstraction between the BL and DAL - if you do it right you'll be able to mix-and-match different physical DAL implementations at once.
If you keep the DTO's and factory in a common assembly (possibly the same one) then it's easy to re-use them with the BL and various DAL implementation - with the caveat that you keep this common class as devoid of dependancies as possble. If you do this you'll be able to add / udpate DAL implemenations without re-compiling and re-deploying the whole system.

Categories