为每个实体提供一项服务?

发布于 2024-11-18 23:50:49 字数 1803 浏览 4 评论 0原文

再次 - 我对 DDD 的事情感到困惑:)

我的架构(我仍在研究它)简而言之看起来像这样:

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

而且我现在正处于我觉得创建和使用一些服务类的时刻。我对此有一些疑问:

1.我应该为每个实体/域对象至少创建一项服务吗?

2.a.服务是否应该有像Find、FINdAll、FindAll(LINQQuery)这样的“查询”方法?

2.b.我是否应该停止在上层(UI)中使用存储库来获取实体集(“查找”类方法)并开始仅使用服务?

3.如果第二个问题的答案是“否” - 我应该以并行方式使用服务和存储库(在 UI 中时,我只需要获取所有实体,我使用 Repository.FindAll,当我需要获取该实体的一些“逻辑”列表时)使用Service.FindXXX方法)?

4.不知何故,我觉得存储库不适合域层 - 我是否应该以某种方式将它们分开,并在 DOMAIN 中只留下特定于域的对象,例如实体和服务?如果是 - 给我一些如何实现这一目标的结构示例。

一些对象的示例:

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 对象,目前主要是 get/set 容器 - 这个问题的背景是删除那个贫乏的模型。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤星 2024-11-25 23:50:49

1.每个实体一项服务?

不。您不需要为一个实体创建一项服务。
在 DDD 中,您将为不会自然映射到单个实体(或值对象)的操作创建服务。良好的服务(来自 Evans):

  • 该操作涉及一个域概念,即不是实体或值对象的自然部分。
  • 接口是根据域的元素来定义的。
  • 该操作是无状态的,

因此一个服务可以消耗许多实体,并且可能有许多实体根本不被单个服务消耗。

2a。服务应该有“查询”方法(..)吗?

不应该。一般来说,这些是存储库方法,不放置在服务上。但是,服务上的操作可能会返回实体集合。

2b.我是否应该停止使用上层 (UI) 中的存储库来获取实体集(类似“查找”的方法)并开始仅使用服务?

这可能是个好主意。通常,当应用程序在 UI 层使用多个存储库时,UI 对多个实体执行域操作。这些操作通常应该在领域层实现;无论是在实体本身,还是在服务中。

3.我应该从 UI 并行使用服务和存储库吗?

最好不要,参见上文;尽管在某些情况下您可以通过这样做快速创建部分 UI。

4。不知何故,我觉得存储库不适合域层...

你是对的,你应该只将存储库接口放在域中。请参阅 Kostassoid 的回答作为示例。

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.

如果没结果 2024-11-25 23:50:49

我的想法:

  1. 服务为业务逻辑提供上层接口。一般来说,您应该将域级实现细节(较低)隐藏在其方法(基本上是命令或查询)后面。一个好的思考方式可能是根据用例或用户故事来命名您的服务方法。并且您不应该提供服务客户端 (UI) 所需的更多功能。

2a.如果您的 UI 需要来自某种类型实体的所有数据,则需要,否则不需要。 FindAll() 几乎不是一个用例。

2b.您应该使用服务中的存储库,这实际上是您应该使用它的唯一地方。

3 参见 2b。

4 是的。您应该在域中保留存储库的接口,但实现应该在数据访问中。然后你可以用一些 IoC 容器粘合所有东西。可能是这样的:

//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 */ }
}

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 */ }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文