Why expose service instead of repository in Onion Architecture?
Asked Answered
L

1

5

I'm digging in on how to structure projects and so I stumbled upon Onion Architecture. As far as I understand it, it's more of a domain-centered-focus architecture instead of a database-driven type.

I'm looking for some github projects to study and learn more about the architecture, so I found this one https://github.com/chetanvihite/OnionArchitecture.Sample

I'm having a hard time understanding:

namespace Domain.Interfaces
{
    public interface IUserRepository
    {
        IEnumerable<User> GetUsers();
    }
}

namespace Services.Interfaces
{
    public interface IUserService
    {
        IEnumerable<User> GetUsers();
    }
}

namespace Services
{
    public class UserService : IUserService
    {
        private readonly IUserRepository _repository;

        public UserService(IUserRepository repository)
        {
            _repository = repository;
        }

        public IEnumerable<User> GetUsers()
        {
            return _repository.GetUsers();
        }
    }
}

How he uses it is by constructor injection.

private readonly IUserService _service;

public HomeController(IUserService service)
{
  _service = service;
}
  1. Do you always expose a service such as IUserService to an app that consumes it? But I noticed, IUserRepository has the same methods as IUserService?

  2. If you say Infrastructure concerns, does it mean or does it involve a database? Or not necessarily? If not, what are examples of infrastructure concerns?

  3. Do you have any recommendation on free projects/github projects that I can download to learn or study further about onion architecture? I understand better on examples

P.S. As I'm learning onion architecture, it always, if not always, at least it mention about DDD. So I guess, I'll be learning DDD also :)

Lowe answered 19/4, 2016 at 17:49 Comment(1)
A very good article about the different kinds of services in DDD, with some code : gorodinski.com/blog/2012/04/14/…Stereoisomerism
B
10

1. Repository vs. Service:

You may want to read an answer on the difference between repositories and services, and/or Martin Fowlers service layer definition. In a nutshell, a repository handles data persistence, whereas a service provides a client-facing API for the business logic.

In the given small example the benefits may not be clear, but imagine the UserService had additional methods such as lockUser(User user) or joinGroup(User user, Group group). The UserService then uses any IUserRepository implementation to actually persist the business logic.

2. Infrastructure Concerns

The infrastructure layer typically talks to external resources, such as file systems, databases or web services. In your example, the IUserRepository is part of the infrastructure layer.

3. Examples

A collection of examples I know (marked by *) and some that I have just found:

Bamboo answered 20/4, 2016 at 6:48 Comment(2)
Thank you much for the references. Really appreciate it but in 1. that doesn't mean I'll have to create the same methods such as lockUser and joinGroup in repository, right?Lowe
Yes, suppose the IUserRepository provides simple CRUD methods for the user object. The UserService.lockUser(userToLock) method then changes the state of the user object (e.g. by userToLock.lock()) and then persists it using the repository (e.g. by _repository.save(userToLock)). The encapsulation makes it easy to add cross-cutting concerns regardless of the actual persistence implementation to the UserService, for example access control, event firing, logging, ...Bamboo

© 2022 - 2024 — McMap. All rights reserved.