Correct approach of referencing in n-layer application - c#

I am a bit new to n-layer architecture and learning it by implementing a simple console app.
I have 3 projects :
DAL with Domain entities and DbContext class.
BLL with Repository class.
Console Application just to run it.
As all my Entities defined in DAL, BLL layer has reference to DAL and looks like:
public class DefaultRepository
{
private DefaultDbContext _repository;
private void SaveChanges()
{
try
{
_repository.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine("Exception were caught");
Console.WriteLine(e.Message);
}
}
public void AddPatient(Patient patient)
{
_repository.Patients.Add(patient);
SaveChanges();
}
public Patient GetPatientById(int id)
=> _repository.Patients.Find(id) ?? null;
public void AddVisit(int patientId, Visit visit)
{
GetPatientById(patientId)?.Visits.Add(visit);
SaveChanges();
}
public DefaultRepository()
{
_repository = new DefaultDbContext();
}
}
The obvious problem is that I cannot use repository in my console application project because console application has no reference to DAL level. The following code occurs compile-time exception.
DefaultRepository repository = new DefaultRepository();
repository.AddPatient(new Patient());
Of course, I can solve it just by adding reference to DAL in ConsoleApplication project. However, I understand, that absolutely destroy the n-layer conception.
So, how should I manage this problem? I googled something about using auto-mappers...

Here I'm not directly giving solution to your use case.But I would like to give right path to implement sophisticated NLayer Architecture application.
What is NLayer Architecture
Layering of an application's codebase is a widely accepted technique
to help reduce complexity and improve code reusability. To achieve
layered architecture, we can follows the principles of
Domain Driven Design. In Domain Driven Design there are four
fundamental layers:
Presentation Layer: Provides an interface to the user. Uses the
Application Layer to achieve user interactions.
Application Layer: Mediates between the Presentation and Domain
Layers. Orchestrates business objects to perform specific application
tasks.
Domain Layer: Includes business objects and their rules. This is heart
of the application.
Infrastructure Layer: Provides generic technical capabilities that
support higher layers. An example of the Infrastructure Layer can be a
Repository implementation used to interact with a database through an
ORM framework, or an implementation for an email provider to send
emails.
There may be additional layers added as necessary. An example being:
Distributed Services Layer: Used to expose application features to
remote clients. There are tools like ASP.NET Web API and WCF that can
provide this layer. These are all common layers of a domain-centric
architecture. There may be minor differences based on implementation.
Overview of layers and structures are shown below:
Here is a solution with five projects for a simple layered application:
If you would like to learn more about this,I highly recommend to study the below mentioned project.It's free and opensource.
ASP.NET Boilerplate

From wiki (https://en.wikipedia.org/wiki/Multitier_architecture):
DAL "Encapsulates the persistence mechanisms and exposes the data".
Patient class is not a part of DAL but is the data that DAL exposes to upper level.
I think there are 2 possible points of view:
DefaultRepository class should be not in BLL but in DAL. Your code in Console should be in BLL
DefaultRepository is a BLL and EntityFramework serves as a DAL.
I any case, your entity "Student" is just a piece of data that can be shared.
If you take more specific pattern like MVC: V (View) and C (Controller) knows about M (Model).
To sum up, you can:
create a 4th project that will be shared by all projects and will contain your entities (or interfaces for these entities).
Don't bother and add link from Console to DAL. The most important that DAL doesn't have links to BLL and console.

Related

Where to put client DLLs in n-tier architecture for calling external API

We have an n-tier architecture with a DAL -> BL -> UI, seperation. In our DAL we have EF for our database access.
We have a requirement to make calls to an external API from a different company. We have been given a couple of client .DLL files with libraries to make the process seamless.
We are struggling to decide where the .DLL files should reside. Should we put them in the DAL and then do the calls in the DAL because it is data access or should we put it all in the BL and make the external calls in there. Therefore not touching the DAL and keeping it isolated and solely for database access.
Would greatly appreciate any advise on this.
Ok, it sounds like you should reference the external assembly on your data access layer beucase the main object of this assembly is to retrieve data. But, when you consume the data access layer on the business layer you also have this principal. I would go by Business Layer. Given it is part of your logic, then you should put this kind of access there.
Another point: If you are not comfortable to reference this assembly on you class library business layer project, you could abstract it into an interface and inject it (by IoC for sample) on your business layer. Using some approach like this, you will keep it on the business layer and isolated the access of this API.
For sample, add it on your Domain Model layer (if you are using one):
public interface IExternalDataService
{
IEnumerable<SomeDto> Getdata();
SomeDto Getdata(object id);
}
On an another class library project you add the refence of the assembly and make the API call, implementing this interface:
public class ExternalDataService : IExternalDataService
{
public IEnumerable<SomeDto> Getdata()
{
// consume the API (dll) here...
}
public SomeDto Getdata(object id)
{
// consume the API (dll) here...
}
}
On your BL classes, depend of the interface:
public class CustomerService
{
public CustomerService(IExternalDataService externDataService)
{
...
}
}
First of all we need to be clear of what exactly is the external DLL providing us, in most of the cases the external dll wraps up the business logic of that particular third party application.
Which, that's why in my opinion, should be kept along in the BL of your application. And hence agreeing with your last statement, to put DAL isolated just taking care of database operations.

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
}
}

What's the recommended folder structure of catalogs in project using IoC

I've read few articles and watched many lectures/tutorials on YT about DI and IoC, but I didn't find any recommended layout of catalogs in VS solution.
I'm talking about the project (a game for example) where you have few classes/interfaces, logger, database provider, wcf services, wpf presentation layer (that's actually different project)...
Is there any pattern project, that shows how should I organize my project, so next, experienced programmer will not waste time figuring out what's going on? Like we're talking about "self commented code", I'm talking about "self commented project structure".
For example, should I put all interfaces into "Interfaces" catalog? Or should I (in case of logger) create "Logger" catalog and put there interface, classes, class with extension methods (all, focused on logging). Code focused on Board, in "Board" catalog. Separate catalog for "Field" etc etc..
Right now the structure looks like that. I'm not sure about "Business" there and Logger. I have interface in different catalog then other logger classes. Should I call Log4Net provider? or adapter? or decorator? It's just a logger class implementing ILogger interface. Here is the screen: link
Here is the sample code (there is no IoC yet, but everybody will notice there will be 3 interfaces there mapped. Very simple):
public class Game
{
public IBoard Board { get; set; }
public Game(IBoard board)
{
Board = board;
}
}
public interface IBoard {}
public class Board : IBoard
{
public IField[,] Fields { get; set; }
public Board(IField field, int boardWidth, int boardHeight)
{
Fields = new IField[boardHeight, boardWidth];
Fields.Initialize();
}
}
public interface IField {}
public class Field : IField {}
public interface ILogger
{
void Log(LogEntry entry);
}
What I usually do is that I have a MyApplication.Core (Class library) layer, which contains all the applications interfaces with as little (read: none) third-party dependencies, e.g. ILogger, ICommand or IQuery<TResult>.
Next I have a MyApplication.Domain (Class library) layer which contains all the application domain specific knowledge - this is the business layer. This is implementations of the core interfaces ICommand, IQuery<TResult>. These implementations then have an dependency on e.g. ILogger. Never concrete implementations.
Then I have the MyApplication.Infrastructure (Class library) which is where all the service interfaces from MyApplication.Core is implemented, e.g. ILogger. Here you can have dependencies on third-party libraries such as Log4Net.
Then last I have the presentation layer, which is in my case usually an MVC applications so I would name this MyApplication.Web.Mvc. All controllers have only dependencies on the interfaces. Never concrete implementations. This layer is also responsible of bootstrapping all the interfaces to the concrete implementations using a Composition Root.
TL;DR:
MyApplication.Core (Application Interface Layer)
MyApplication.Domain (Business Logic)
MyApplication.Infrastructure (Implementations of Application Interface Layer)
MyApplication.Web.Mvc (Presentation and Composition Root Layer)
From Microsoft's "Common web application architectures".
The Application Core Project
The Application Core holds the business model, which includes entities, services, and interfaces. These interfaces include abstractions for operations that will be performed using Infrastructure, such as data access, file system access, network calls, etc. Sometimes services or interfaces defined at this layer will need to work with non-entity types that have no dependencies on UI or Infrastructure. These can be defined as simple Data Transfer Objects (DTOs).
The Infrastructure Project
The Infrastructure project typically includes data access implementations. In a typical ASP.NET Core web application, these implementations include the Entity Framework (EF) DbContext, any EF Core Migration objects that have been defined, and data access implementation classes. The most common way to abstract data access implementation code is through the use of the Repository design pattern.
In addition to data access implementations, the Infrastructure project should contain implementations of services that must interact with infrastructure concerns. These services should implement interfaces defined in the Application Core, and so Infrastructure should have a reference to the Application Core project.
The ASP.NET Core Web App Project
The user interface layer in an ASP.NET Core MVC application is the entry point for the application. This project should reference the Application Core project, and its types should interact with infrastructure strictly through interfaces defined in Application Core. No direct instantiation of or static calls to the Infrastructure layer types should be allowed in the UI layer.
A starting point repo for Clean Architecture with ASP.NET Core
https://github.com/ardalis/CleanArchitecture

UI layer dependency in DDD

My current project is organized in this way:
Domain Layer -> Domain objects and Repository Interfaces
Infrastructure -> Repository implementation
Application Layer -> Services in a MVVM pattern
Presentation -> Accessing only Service Layer and working with ViewModels
I´m using an IoC Container (SimpleInjector). My Services receives an IRepository in the constructor like:
public CustomerService : ServiceBase
{
public CustomerService(ICustomerRepository repository, IUnitOfWork<CustomerContext> uow)
{
...
}
}
My question is:
To inject a Repository in the Service, my Presentation Layer should reference the Domain Layer. It´s ok to add this reference? Shouldn't my presentation layer have reference only to the Infrastructure and the Application layer?
Yes, that's OK.
You need a reference to all components from the composition root (which usually resides in the presentation layer).
I understand it feels a bit strange at first, but you need to differentiate between a DLL-dependency and a hard class dependency. It's OK if your presentation layer depends on DLL's, it's not OK when a view depends on a SQL-repository (as an example).
I have written a blog post about this with some more information:
http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/

Repository Pattern with 2 services & 2 dataccess layers - C# DDD?

Can anyone help, I have 2 applications and they are nearly identical. they have a completely different presentation layer (web) and the business logic and database are nearly identical. Basically one app has some things that the other doesn't.
so i was wondering if i can do the following without breaking any rules etc
Each app has their own presentation layer.
Each app has their own service layer.
Each app has their own data access layer.
Each app shares another service layer.
Hence the shared service layer both apps can access as the business logic is identical, but they both have another service layer which has 5 or 6 methods in there which are specific to that actual app
The data access layer - I don't see anyway of sharing this as there are 2 different db's with entity framework hence its got the EDM in there so its not dynamic - and the tables differ slightly.
I could use IOC on the shared data access layer I suppose
Would anyone help or comment weather this is good practise.. What I didn't want to do is have only a separate service layer when a lot of it is shared..
Is this a good idea? Maybe i have got it wrong, is there a better way?
As Arjen de Blok said, your business entities should use a repository, a repository is an object with methods to query, update or insert domain entities.
The interface which describes your repository belongs to your domain layer, but the implementation belongs to the infrastructure layer (DAL).
You can share the domain and infrastructure libraries between your two projects. If these two projects should retrieves their data through a shared web service or a shared database, you just have to choose (i.e inject) the correct implementation of your repository (your domain objects know only about the interface of your repository, not about the concrete type)
If the business logic is mostly identical then you should focus to this first.
If you want to do DDD then you should identify your entities and (business) services first and place these in a single library.
These entities and business services should talk to your infrastructure layer (your DAL).
If the infrastructure layer is very different in these two applications then try to work with interfaces. So wrap the intfrastructure layer with interfaces and only talk from the domain layer to your infrastructure layer via these interfaces.
To bind your business logic to your infrastructure's implementation you could use IoC/DI.
You could unify the DAL with a Repository interface. You could then implement the interface across projects. You will probably end up with a EF Repository base class as well. You could apply a similar technique to the services, leverage a common interface and then specialize the service implementations.

Categories