I have 3 projects in .NET
DAL (data access layer)
UI (user interface)
BI ( logic)
DAL call the BI (services)
And The BI Call the DAL (repository)
my problem in my UI project in (global.asax)
- I call my injector to Register my classes
public Application_Start()
{
......
container.Register<IService1, Service1Impl>();
container.Register<IService2, Service2Impl>();
}
But How I can Register my DAL Class without call them in UI Project
Else I have to add my in DAL project in My UI project
The Application_Start is not part of User Interface layer. The Application_Start is part of the Composition Root, which is a layer of its own. You only implicitly decided to place both the Composition Root and the User Interface Layer in the same assembly, which is fine.
For more details, about this, see this article: Understanding the Composition Root.
You chose onion-architecture and input-point is UI project. Your UI project must have links to DAL and to BI projects.
If you want to create independent modules in your application, you can choose microservices architecture.
Related
I am implementing a Clean Architecture. I have four projects: Domain, Application, Infrastructure, and Presentation.
I have repository implementations defined in the Infrastructure. And I have the Repository Interfaces in the Domain.
I also have Services with a corresponding repository injected. For example, StudentService. I inject the StudentRepository into the StudentService.
My question is, where do I put the interface IStudentService? Should it reside in the Domain along with the interface IStudenRepository? Or is it more proper to place it in the Application?
I currently have my IStudentService in the Application project. But my understanding is to have loose coupling and placing all Interfaces in the Domain project. Is my understanding correct?
It is generally a good practice to place interface definitions in the Domain layer of a Clean Architecture application. This is because the Domain layer represents the core business logic of the application, and interfaces are an important part of defining the contract for that logic. By placing interface definitions in the Domain layer, you can ensure that the Domain is decoupled from the implementation details in the other layers of the application.
For example, in your case, the IStudentRepository interface would be defined in the Domain layer because it represents the contract for how the StudentService can interact with the student data store. The IStudentService interface would also be defined in the Domain layer because it represents the contract for the business logic related to students.
By placing both of these interfaces in the Domain layer, you can ensure that the Domain is decoupled from the implementation details in the other layers of the application. This makes it easier to change the implementation of these interfaces without affecting the rest of the application.
In summary, it is generally a good practice to place interface definitions in the Domain layer of a Clean Architecture application in order to ensure loose coupling and separation of concerns.
To implement Clean Architecture follow the following steps:
Domain Project:
Domain should have just entities such as "Student" Entity.
Application Project:
Application should have interfaces and services and the implementation of services.
Infrastructure Project:
Infrastructure should have the implementation of interfaces that are defined in the Application, and DbContext class.
The presentation should have the UI.
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.
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.
So my problem is the following. My solution contains the following projects (with references):
Presentation Layer, contains Views (has a reference to Application Layer)
Application Layer, contains ViewModels (has a reference to Domain and Persistence Layer)
Domain Layer, contains all Models (no reference to anything)
Persistence Layer, stores data with Entity Framework (reference to Domain Layer)
All right, now I want to use Dependency Injection to decouple my ViewModels from Services and other stuff. Because I'm also using a dialogs, I also need to inject the IDialogService with the implementation DialogService.
Now, the DialogService uses some Presentation-specific DLLs which are only in the Presentation project so I had to implement the IDialogService interface in the Presentation project, but the Unity-Container is in the Application Layer. I think you can see what my problem is: I only have a reference from Presentation Layer to Application Layer, not the other way.
Am I doing this right and how can I solve this problem?
You are missing a layer: the Composition Root layer. This is the top-most layer of your application and it references all other layers in you application. Often you see that this layer is put into the same assembly as the presentation layer (which is fine, because layers are logical artifacts, while assemblies are physical artifacts). In the case of WPF however, it is very easy to move all WPF related stuff to a different assembly and let the start-up project consist of nothing more than the bootstrapping logic (with the container) that wires everything together.
So in general you shouldn't let each assembly be responsible of its own wiring, because that would cause a needless dependency on the container. In general only the composition root has to take a dependency on your DI library.
Also see this related question.
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/