1

我有一个使用 NHibernate 和 ASP.Net MVC 的项目。该应用程序旨在允许用户跟踪某些数据,然后根据输入的数据生成统计视图。到目前为止,我的应用程序的结构如下所示:

NHibernate 层:包含Repository<T>UnitOfWork类,以及实体映射定义。

核心/服务层:包含通用EntityService类。目前,这只是通过IUnitOfWork接口定义事务范围,IRepository以提供更高级别的数据访问服务。

表示层(MVC 应用程序):尚未实现,但包含通常的东西加上依赖注入。

我有一些问题:

  1. 允许我的 MVC 应用程序处理所有层的依赖注入是糟糕的设计吗?例如,除了将EntityService实例依赖注入到控制器中,它还将处理依赖注入IRepositoryEntityService类中。服务层是否应该自己处理这个问题,即使这意味着在两个不同的地方执行依赖注入?

  2. 我应该在哪里生成我的统计数据?这个业务逻辑似乎不属于我的服务层,目前它只包含实体类型定义和一个用于修改和访问实体属性的接口。我对此有一些想法,但我不确定我最喜欢哪个:

    • 保持我的服务层不变并创建一个单独的统计项目 - 这完全独立于将要使用的实体类型,这意味着我的 MVC 控制器将必须在我的业务实体和我的(可能是静态的)统计数据之间传递原始数字信息类。这是一个非常巧妙的分离,但可能意味着大量业务逻辑仍保留在表示层中。
    • 创建一个统计项目;但是,在这个项目中的类和我的业务实体之间创建一个紧密耦合。例如,我不会将Reading对象的传递给方法,而是传递整个对象(或将它们定义为扩展方法)。这会将业务逻辑从我的 MVC 应用程序中移出,但紧密耦合似乎有点混乱。
    • 将我的所有业务逻辑保留在我的服务层中。定义 的强类型子类EntityService,因此我的服务既包含特定于实体的业务方法,也包含数据存储方法,同时将实体类本身保持为纯数据容器。为任何通用统计处理创建一个单独的统计项目,并通过我的派生服务类调用其方法。我的服务类有效地将业务功能与IRepository<T>.

我对第三种选择犯了错误,但有人有什么想法吗?替代建议?

提前致谢!

4

2 回答 2

3

初步观察:

我喜欢你描述你的项目的方式,我只是不明白为什么你的数据访问层(DAL)被称为 NHibernate 层:这与你没有使用技术名称来描述逻辑的所有其他层很奇怪层(正确)。所以我建议你将它重命名为 DAL,并用它来从 NHibernate 中抽象出你的应用程序。

我对你的问题的看法:

  1. 绝对没有。将依赖注入应用于所有层是件好事。几个或它好的原因:

    1.1测试:您可以模拟 DAL 接口并使用另一个 DI 配置文件对不带 DAL 的服务层进行单元测试。以同样的方式,您可以模拟 Web 控制器层的服务等。

    1.2不同的 DAL 实现:假设您需要不同的 DAL 实现(NOSQL、SQL 或 LINQ 而不是 NHibernate 等)技术用于您项目的不同部署或将来进行扩展。您可以轻松地维护不同的 DI 配置文件。

  2. 您可以在不同的项目中部署相同的层。以同样的方式,您可以拥有一个包含不同图层的项目。我认为它们的关系是正交的:项目描述的是物理(开发时间和运行时间)实现。层是合乎逻辑的。所以最初我会用第三个选项保持简单。我只是不明白您为什么要针对此选项说以下内容:

为任何通用统计处理创建一个单独的统计项目,并通过我的派生服务类调用其方法。我的服务类有效地将业务功能与 IRepository 创建的存储功能合并。

我将统计信息视为一项或多项服务,因此您可以将其实现为具有服务层内类的命名空间。而且,与任何其他服务一样,您可以注入 DAL 存储库类。而且,与任何其他服务/DAL 一样,模型类可以在不同的服务和 DAL 类之间共享。


StatsService.AverageReadingFor(Person p, DateTime start, DateTime end)听起来不错。

有几个实现选项:

  1. 使用底层存储库功能(例如:SQL avg 函数)
  2. 使用也可以使用依赖注入实现的观察者模式
  3. 使用面向方面的编程。以Spring.Net 章节为例。

如果您有多个服务层实例(多个服务器),则必须对 2 和 3 进行调整,以便使用消息传递系统进行进程外通信。

于 2012-11-18T18:09:10.550 回答
0

只是一个更新——关于我的第二个问题,我决定定义一个IStatsService<T>期望将一个IEntityService<T>传递给它的构造函数的。我将使用它来对业务实体进行通用统计处理,并创建更多接口来实现IStatsService<T>我需要更多特定于类型的信息。

希望这会帮助那些一直在为类似问题挠头的人!

于 2012-11-19T13:05:38.367 回答