0

我正在实现一种使用单个数据存储但分开查询和命令模型的CQRS形式。对于我正在实施DDD的命令方面,包括存储库,IoC和依赖注入。对于查询方面,我使用here所述的Finder模式。基本上,查找器类似于存储库,但仅限于查找方法。CQRS - 接口和依赖注入是否需要读取模型?

因此,在我的应用程序中,在我的DAL中,我使用ADO.net和原始SQL来执行我的查询。 ADO.Net的东西都被抽象成一个漂亮的帮助器类,这样我的Finder类就可以简单地将查询传递给ADO帮助器,该帮助器返回查找器/映射器类转换为读取模型的通用数据对象。

当前,Finder方法(如我的命令存储库)通过注入到我的控制器的接口进行访问,但我想知道接口,DI和IoC是否对查询方过度杀手,因为我已经阅读了有关CQRS的阅读方建议使用“瘦数据层”。

为什么不直接访问我的Finders?我理解接口和DI的论点。即分离关注点和可测试性。在SOC的情况下,我的DAL已经通过使用映射器类并将ADO.net内容放入辅助类中分离出数据库特定的逻辑。就测试而言,根据this question单元测试读取模型不是必需的。

public class PersonController : Controller 
{ 

    private IPersonFinder _person; 

    public PersonController(IPersonFinder person) 
    { 
     _person = person; 
    } 

    public ActionResult Details(int id) 
    { 
     Person person = _person.GetByID(id); 

     // TODO: Map person to viewmodel 


     return this.View(viewmodel); 
    } 

} 
+0

但是如果你想将一些横切关注点应用到你的'PersonFinder'上呢?当你将它应用到静态类时,这将是非常困难的(和很多重复的代码),而如果一个接口被注入,你可以自由地用装饰器,代理,拦截器或其他任何模式来包装该实例在你的工具箱中。 – Steven

回答

2

是否使用 IOC和DI:

因此,在总结,读模式,我能做到这一点:

public class PersonController : Controller 
{ 
    public ActionResult Details(int id) 
    { 

     var person = new Person(); 
     person = PersonFinder.GetByID(id); 

     // TODO: Map person to viewmodel 


     return this.View(viewmodel); 
    } 

} 

相反的呢?这是不好的屁股!无论如何,第二个版本更好,因为它不依赖于静态类。使用静态会打开潘多拉盒子,不要这样做,因为所有使用静态的原因是不好的。

你真的没有得到任何好处,使用静态类,一旦你已经使用DI容器,没有额外的成本。你直接使用Finders,但你让DI容器实例化一个而不是你调用一个静态对象。

更新

薄读出层指的是使用简化的模型读代替富域对象。它与DI无关,无论查询服务是如何构建的或由谁来建立都无关紧要,重要的是不要将业务对象包含在查询中。

+0

是的,你对静态类的事情是正确的,我的错误。我将编辑问题以在控制器方法内实例化类。我的担忧仍然是,通过在读取模型中使用DI,我正在摆脱阅读模型的薄数据层的概念。 –

+0

您的阅读模型是DTO。您正在使用DI来保持事物解耦,与读取模型无关。瘦数据层是关于让查询服务直接使用简化模型而不是复杂的复杂模型。不要过分坚持这一点,并保持你的DI容器。 – MikeSW

+0

我的解释是保持整个过程,即从数据库获取数据并将其显示在屏幕上。你是否建议我应该更加狭隘地看待这个问题,并专心致力于保持查询方面的优势并填充我的dtos? –

1

读/写分离与编码技术如依赖注入完全无关。您阅读的模型比以前的组合读/写模型服务的用途更少。你可以考虑抛弃所有的服务器端代码,只使用数据库的本地REST API吗?你可以连线你的控制器直接用SQL查询数据库并将数据作为JSON返回?你需要一个通用的类库来处理特定的读请求吗?

+0

我的观点是,像依赖注入这样的东西会增加架构开销。因此,读和写的分离与编码技术有关,因为建议读模型保持精简。 –