I am working in a Web Api project that has the following project structure:
Root
Controllers
Orchestrators
Managers
Services
etc
The Controllers depend on Orchestrators.
The Orchestrators depend on Managers.
The Managers depend on Services. The Services are making calls to external dependencies e.g., third party APIs or data stores.
So for every flow, an incoming HTTP request follows this path:
Controller <--> Orchestrator <--> Manager <--> Service
Sample code:
AccountsController.cs
public class AccountsController
{
private readonly AccountsOrchestrator accountsOrchestrator;
public AccountsController(AccountsOrchestrator accountsOrchestrator)
{
this.accountsOrchestrator = accountsOrchestrator;
}
[HttpGet("GetAllAccounts")]
public async Task<ActionResult<IEnumerable<string>>> GetAllAccounts(string input)
{
var accounts = accountsOrchestrator.GetAllAccounts(input);
return new OkObjectResult(accounts);
}
[HttpGet("GetAccountById")]
public async Task<ActionResult<IEnumerable<string>>> GetAccountById(string input)
{
var account = accountsOrchestrator.GetAccountById(input);
return new OkObjectResult(account);
}
}
AccountsOrchestrator.cs
public class AccountsOrchestrator
{
private readonly AccountsManager accountsManager;
public AccountsOrchestrator(AccountsManager accountsManager)
{
this.accountsManager = accountsManager;
}
public async Task<IEnumerable<string>> GetAllAccounts(string input)
{
// Validate input
if (string.IsNullOrEmpty(input))
{
return Enumerable.Empty<string>();
}
var accounts = await accountsManager.GetAllAccountsFromExternal(input);
return accounts;
}
}
AccountsManager.cs
public class AccountsManager
{
private readonly ExternalDependency externalDependency;
public async Task<IEnumerable<string>> GetAllAccountsFromExternal(string input)
{
// Validate input
if (string.IsNullOrEmpty(input))
{
return Enumerable.Empty<string>();
}
var accounts = await externalDependency.CallExternalService();
return accounts;
}
}
ExternalDependency.cs
public class ExternalDependency
{
public async Task<IEnumerable<string>> CallExternalService()
{
await Task.Delay(500);
}
}
There are more than a dozen Controllers which leads to more than a dozen Orchestrators and so on and so forth.
- Is it good enough?
- Is there a better approach for that?
- Is there a pattern that specifically targets these scenarios?