One service for each entity?

不打扰是莪最后的温柔 提交于 2020-01-01 03:46:07

问题


Again - i'm confused about DDD things :)

I have architeture (I'm still working on it) that in short hand looks like that:

DataLayer:
 EntityDao -> Implementing domain layer interfaces (NHibernate)
DomainLayer:
 EntityRepository -> Repository for each entity with injected Dao
 DomainObjects/Entitys -> Some logic
UI
 ASP.Net MVC

And I'm right now in that point where I feel to create and use some Service class. I have some questions with that:

1.Should I create at least one service for each entity/domain object ?

2.a.Should services have "query" method like Find, FIndAll, FindAll(LINQQuery)?

2.b.Should I stop to use Repositorys in upper layers (UI) to get sets ("Find"-like methods) of entity's and start to use only services?

3.If answer on 2 question is No - Should I use Services and Repository in parallel fashion (When in UI I just need to get all entity's I use Repository.FindAll, when I need to get some "logical" list of that entity's i use Service.FindXXX method)?

4.Somehow I feel that Repositorys don't fit in Domain layer - should I separate them somehow and in DOMAIN leave only domain specific objects like Entity's and Services ? If Yes - give me some structure example how to achieve that.

Examples of some objects:

Dao:

public class NHibernateDao<T> : IDao<T>
{
    public NHibernateDao() { }

    public T Get(object id)
    {
        T entity = (T)NHibernateSession.Get(entityType, id);
        return entity;
    }
    public T Load(object id)
    {
        T entity = (T)NHibernateSession.Load(entityType, id);
        return entity;
    }
    public virtual T Update(T entity)
    {
        NHibernateSession.Update(entity);
        return entity;
    }
    ...

Repository:

public class BaseRepository<T>:IRepository<T>
{
    private DataInterfaces.IDao<T> mDao;

    public virtual T Get(object id)
    {
        return mDao.Get(id);
    }
    public virtual void Delete(T entity)
    {
        mDao.Delete(entity);
    }
    public virtual T Update(T entity)
    {
        return mDao.Update(entity);
    }
    public virtual IQueryable<T> FindAll()
    {
        return mDao.FindAll();
    }
    ...

Domain objects, at the moment , it's mainly get/set container - background of this question is to remove that anemic model.


回答1:


1. One service per entity?

No. You do not need to create one service for one entity. In DDD you would create services for operations that do not naturally map to a single entity (or value object). A good service (from Evans) :

  • The operation relates to a domain concept that is not a natural part of an entity or value object.
  • The interface is defined in terms of elements of the domain.
  • The operation is stateless

So a service can consume many entities and there might be many entities that aren't consumed by a single service at all.

2a. Should services have "query" methods (..)?

No. Generally speaking those are repository methods and are not placed on services. However, there can be operations on a service that return a collection of entities.

2b.Should I stop to use Repositories in upper layers (UI) to get sets ("Find"-like methods) of entity's and start to use only services?

That might be a good idea. Often, when an application uses many repositories in the UI layer, the UI performs domain operations on multiple entities. These operations should typically be implemented in the domain layer; either in the entities themselves, or in services.

3. Should I use Services and Repositories in parallel from the UI?

Better not, see above; although there might be situations where you can quickly create part of your UI by doing so.

4. Somehow I feel that Repositoriess don't fit in Domain layer ...

You're right, you should only put repository interfaces in the domain. See Kostassoid's answer for an example.




回答2:


My thoughts:

  1. Services provide upper level interface for business logic. Generally, you should hide your domain level implementation details (which is lower) behind it's methods, basically commands or queries. A good way of thinking could be to name your service methods after use cases or user stories. And you shouldn't provide more functionality that required by service clients (UI).

2a. If your UI needs all data from entities of some type then yes, otherwise no. And FindAll() is hardly a use case.

2b. You should use Repositories from your Services, that's actually the only place where you should use it.

3 see 2b.

4 Yes. You should leave interfaces for repositories in your Domain, but implementation should be in Data Access. Then you can glue everything with some IoC container. Could be like this:

//in domain
public interface IUserRepository {
    User GetById(Guid id);
}
//in data access
public class UserRepository : IUserRepository
{
    public UserRepsitory(/* some orm specific dependencies */) { }
    public User GetById(Guid id) { /* implementation */ }
}


来源:https://stackoverflow.com/questions/6606205/one-service-for-each-entity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!