C#服务层设计模式

我们正在研究创建一个新项目,并希望使用Repository和Service层模式进行探索,目的是创建松散耦合的代码,该代码使用模拟库进行完全可测试.

请参阅下面的基本架构思想.我们将使用接口来描述这些存储库,并将它们注入服务层以删除任何依赖关系.然后使用autofac,我们将在运行时连接服务.

public interface IOrderRepository
{
    IQueryable<Order> GetAll();
}

public class OrderRepository : IOrderRepository
{
    public IQueryable<Order> GetAll()
    {
        return new List<Order>().AsQueryable();
    }
}

public class OrderService
{
    private readonly IOrderRepository _orderRepository;

    public OrderService(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }

    public IQueryable<Order> GetAll()
    {
        return _orderRepository.GetAll();
    }
}

public class EmailService
{
    public void SendEmails()
    {
        // How do I call the GetAll method from the order serivce
        // I need to inject into the orderService the repository to use
    }
}

有几个问题,我们无法找出最好的前进方向.

1)如果服务正在复制CRUD方法,我们可能会重现代码,没有真正的好处.或者UI应该直接调用存储库?

2)当服务需要调用一个服务时会发生什么.在上面的示例中,如果电子邮件服务需要获取所有订单,那么我们将订单服务注入到电子邮件服务中?

希望这是有道理的

解决方法

看看域驱动设计. DDD将大多数逻辑移动到实体(订单,电子邮件)中,并让他们使用存储库.

1) Should the service be reproducing the CRUD methods,as it appears we may be reproducing code with no real benefit. Or should the UI call the repositories directly?

当您发现自己在实体之外编写业务逻辑时,将使用DDD中的服务.

2) What happens when a service needs to call another service. In our example above if Email Service needs to get all the orders,do we inject the order service into the Email service?

在构造函数中注入它.但是,订单服务应该发送电子邮件,而不是其他方式.

DDD方法将创建一个OrderNotificationService,它接收域事件OrderCreated并构成通过EmailService发送的电子邮件

更新

你错过了我重复的逻辑永远不会很好.当我的存储库有一个时,我不会把一个名为GetAll的服务中的方法.我也不会将该方法放在我的实体中.

示例代码

var order = repository.Create(userId);
order.Add(articleId,2);  
order.Save(); // uses the repository

Order.Send()应该创建一个OrderNotificationService可以捕获的域事件.

UPDATE2

Repository.Create只是在一个地方获得所有域模型创建的工厂方法(google factory method pattern).它在db中没有做任何事情(尽管可能在将来的版本中).

对于order.Save它将使用存储库来保存所有订单行,订单本身或任何其他将需要的.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...