Alle
Alle

Reputation: 11

C# DDD Where Infrastructure models should be?

Using DDD in c# and Clean architecture / Onion architecture i have 4 projects API, Application, Domain and Infrastructure. If i have some external api call for example get user profile from github.

interface IGitHubService: Task<GitHubUserProfile> GetProfile(int id); class GitHubService : IGitHubService { implementation }

Where those 2 should be? I used to create service contracts in Application/Contracts/IGitHubService.cs and implementations in Infrastructure layer.

Where should be placed the GitHubUserProfile, in domain layer, what folder?

Should i create Models folder in Domain layer?

Upvotes: 0

Views: 357

Answers (2)

desertech
desertech

Reputation: 1029

If you intend to implement IGitHubService purely to access GitHub-database, then I would place this interface under Domain and place implementing class (GitHubService) under Infrastructure (and call them IGitHubRepository, GitHubRepository respectively).

But if IGitHubService's implementation involves more than database access, e.g. checking response and throwing exception under some condition, then I would place both interface and implementing class under Application, while creating IGitHubRepository and GitHubRepository for pure database access (as described above).

As for models, if your business model dictates that you should align with provider's model, then you can place GitHubUserProfile under Domain and have GetProfile returning it.

However if you aim to have a somewhat different model, then have GitHubUserProfile under Infrastructure and create MyGitHubUserProfile under Domain. You'll need, of course, to map provider's model to your model. This conversion should take place inside implementation (GitHubRepository, Infrastructure).

class MyGitHubUserProfile // Domain
{
    // Properties
}

interface IGitHubRepository // Domain
{
    Task<MyGitHubUserProfile> GetProfile(int id);
}

interface IGitHubService // Application
{
    Task<bool> IsProfileValid(int id);
}

class GitHubService : IGitHubService // Application
{
    public Task<bool> IsProfileValid(int id)
    {
        MyGitHubUserProfile profile = this.GitHubRepository.GetProfile(id);

        // Check profile here
    }
}

class GitHubUserProfile // Infrastructure
{
    // Properties
}

class GitHubRepository : IGitHubRepository // Infrastructure
{
    public Task<MyGitHubUserProfile> GetProfile(int id)
    {
        GitHubUserProfile infraProfile = this.HttpClient.GetAsync(...);
        MyGitHubUserProfile domainProfile = this.Convert(infraProfile);
        return (domainProfile);
    }
}

Upvotes: 0

plainionist
plainionist

Reputation: 3563

The guiding principle here should be the Dependency Inversion Principle. Your interface should be in the application layer (as you already stated). As a consequence GitHubUserProfile needs to be at least in the application project as well.

Now you have to decide how central the GitHubUserProfile is for your application. If it is just one aspect among many others i would suggest to put it next to IGitHubService.

If it is very central entity for your application I would suggest to move it into the Domain project.

Whether you need folders in your domain project to separate concerns further certainly depends on how much code and how many different concerns you have in this project.

Upvotes: 0

Related Questions