I am pretty new to Clean Architecture in C#.
Based on the details my understanding was all the business logic must be in Application Layer and any infrastructure level things (DB Crud operations, Message handlings) must be in infrastructure layer.
So I have started the development, but found there is no dependency with infrastructure layer in application layer. Even why they are saying keep the business logic in application layer and infra operations in that layer.
Without that dependency how can I access the CRUD operations in infra layer.
Also there is dependency with Applicaiton layer in infrastructure layer which is I didnt understand.
Someone please help because I really got stuck with it. I have few methods in my application layer and I need to write the output into DB as well, which I dont know how to implement.
So simple it would be like this based on the description
Application Layer
IMessageBroker.cs
Public class IMessageBroker
{
Task<int> pushtoqueue(string queue, string message);
}
myservice.cs
public class myservice
{
public void MyMethod
{
//Here I need to call the pushtoqueue method which I dont know
}
}
Infrastructure Layer
MessageBroker.cs
public class messagebroker :Imessagebroker
{
public task<int> pushtoqueue(string queue, string message)
{
// here the queue pushing code comes
}
}
DependencyInjection.cs
services.Addscoped<IMessageBroker, MessageBroker>();
Please share your thoughts..
Environment
.NET 6
Azure Function Apps 4.0
CodePudding user response:
The sample you linked to uses a concept called "inversion of control" (IoC). Adapted to your sample and defined in a (lengthy) sentence, this concept is about inverting the dependency from the Application layer to the Infrastructure layer so that the Application layer defines its requirements towards the Infrastructure layer (in form of interfaces) and can work with any Infrastructure layer that implements these interfaces.
If you look at the diagram in the overview section, there is an arrow from the Infrastructure layer to the Application layer. This expresses the dependency from the Infrastructure layer on the Application layer.
In your case, the components serve the following purpuse:
IMessageBroker
: interface in Application layer that defindes the requirements that the Infrastructure layer has to fulfill.MyService
: service class that uses infrastructure components. An instance of typeIMessageBroker
should be injected into the class in order to access the message broker.MessageBroker
: concrete implementation ofIMessageBroker
.
The benefit of this approach is that you can easily replace infrastructure components without changing the application layer. While changing from one message broker to another might be comparatively seldom, being able to use mock objects when testing MyService
is invaluable.
To answer the original question: how can you call the pushtoqueue
method?
Just inject an instance of IMessageBroker
into MyService
and use it there:
public class MyService
{
private readonly IMessageBroker _msgBroker;
public MyService(IMessageBroker msgBroker)
{
_msgBroker = msgBroker;
}
public void MyMethod
{
//Here I need to call the pushtoqueue method which I dont know
_msgBroker.PushToQueue("queue", "message");
}
}
In your sample, you already add a registration of IMessageBroker
to the IoC container, so the instance is injected when creating MyService
.
As a side note: following naming conventions increases readability for fellow programmers. I've changed some of the names from the question. For an overview of the C# naming conventions see this link.