4

I'm digging on how to structure projects and so I stumble into Onion Architecture. As to how I understand it, its more on 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 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 use 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 to IUserService?

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

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 :)

3
  • 1
    AFAIK onion architecture only covers the separation of UI, Domain (business logic) and Data. It does not say how many middle layers you should have among those. If you feel like creating a service, do so. Nonetheless, if all the user service is doing is hiding the use of user repository, then the service is pretty much useless.
    – Andy
    Commented Apr 19, 2016 at 18:14
  • @DavidPacker That's what I also thought about the service. In his code is there any other reason why you'd want to expose service instead of exposing repository directly?
    – Boy Pasmo
    Commented Apr 19, 2016 at 18:19
  • Note that asking for off-site resource recommendations such as sample projects is considered off-topic here, so I edited out that subquestion.
    – Ixrec
    Commented Apr 19, 2016 at 18:20

2 Answers 2

10

Q: Do you always expose a service such as IUserService to an app that consumes it?

We often do it. Sometimes by inertia others for testing, but most of the time to "draw" boundaries, verticals, etc. It's a common practice which brings us attractive benefits at a small cost.

Ideally, services orchestrate calls between components of different boundaries so that the consumer doesn't need to know about these other components. Services are especially relevant in designs in which data and behaviour are drastically decoupled. In such designs, services are the business layer.

Q: But I noticed IUserRepository has the same methods to IUserService?

It sounds like a design flaw to me. It's over-engineering. They don't provide any relevant abstraction, there's nos business logic. The transaction span is as wide as the one beneath the repository.

So, should we allow consumers to know about IRepository? Yes. If there's no business logic at all if your domain only provides basic CRUD operations and no business rules are required. Why not? Keep it simple.

Why? Simplicity. Unnecessary complexity makes code hard to maintain, hence expensive. Not only for your customer. It's also expensive for you.

Q: If you say infrastructure concerns, does it mean or does it involve databases?

Yes, but databases are not the only ones. There could be more.

  • access to the email server
  • access to the message brokers
  • access to queues
  • access to remote storage (DBs, File system, etc)
  • access to remote devices
  • access to indexers
  • access to 3rd party services

Think in an assembly line. The goal of the line is to assemble things and to this end, it needs an energy supply. Whatever is supplying the line with energy is considered an infrastructure service. The source of the energy won't make the assembly line change its goal, but the way it's supplied could.

So yes, the access to databases can be considered infrastructure concern in onion architectures. Onion architecture considers databases to be remote elements to be communicated with. They are no longer centric and should be possible for us to change them without having to change the domain.

6
  • I see. So always expose service even though it contains same method to the repository. Got it. But is there any cases that repository and service does not contain the same method? Do you have any comment on my question #2?
    – Boy Pasmo
    Commented Apr 19, 2016 at 18:26
  • The question is why your service has no business? In any service layer is expected to have business. Even if doesn't have, then its business is to be a proxy or a concentrator of repositories, whatever. But you should think in terms of business. What I'm exposing? My data model? My service s? Think in any webservice. Google for example. Do you think google is exposing its data or its business? All these concepts are Facto standards so is open to use'm or not. But it makes a great big deal better to do it.
    – Laiv
    Commented Apr 19, 2016 at 18:37
  • Thank you so much. Do you have any comments on this? My question #2. If you say Infrastructure concerns, does it mean or does it involve database? Or not necessarily? if not, what are examples of infrastructure concerns?
    – Boy Pasmo
    Commented Apr 19, 2016 at 19:02
  • i have edited my answer. Anyways wait for more opinions ;-). As I said, this subject is open to opinions
    – Laiv
    Commented Apr 19, 2016 at 19:13
  • It sounds a design flaw to me. It's a symptom of overengineering To be fair, just becauser you use a service layer doesn't mean that every service has to therefore add functionality to its related repository. For example, there may be additional business logic in the DocumentService and the PictureService (which means they're not just a passthrough for the DocumentRepository and PictureRepository), but the UserService is one that doesn't actually need additional logic and thus looks like a passthrough. If some services has relevant purpose, the service layer has purpose.
    – Flater
    Commented Jun 3, 2019 at 10:21
4

Onion architecture means hiding dependencies to infrastructure behind an interface.

All components that use IUserService do not need to know wether the service is implemented using soap, rest, http or anything other infrastructure related.

The actual UserService implementation uses a repository interface IUserRepository as implementation detail. The UserService does not need to know which infrastructure the implementation UserRepository uses (odbc, odedb, mssql-native, ....)

But I noticed IUserRepository has the same methods to IUserService?

This is coincidence.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.