1

我被要求构建不同的WCF服务,每个服务都针对 sql 进行其他工作。

我们有5 个分贝。所有 db 的 + 连接字符串都在1 个xml 文件中。(文件系统文件)

这些服务托管在WASiis 7.5 下。

由于每个服务都应该从 db 读取,每个服务都引用一个DAL dll文件。

所以这里是我们的组件:

在此处输入图像描述

我想将 xml 数据读取到CACHE(在第一次请求时)并从现在开始 - 从缓存中读取。(读取文件每个请求都是不可能)。

  • 想法 #1 = dll ,在他的 ctor 中,首先请求将读取 xml 文件并将其加载到缓存中。

所以dal看起来像这样:

在此处输入图像描述

所以现在每个服务都可以通过属性访问 DLL 的缓存对象。(一个优点是在处理cache dependency单个文件时 - 所以当它发生变化时,我们应该只重新加载到一个位置)。

  • 想法 #2 = 当服务启动时,将 xml 加载到它的 cache.

所以现在,每个服务将如下所示:

服务#1:

在此处输入图像描述

服务#2:

在此处输入图像描述

..

缺点是同一文件上有许多缓存依赖项

Question :

根据最佳实践经验和设计模式POV:哪种方式是首选方式?

ps xml文件更改频率1/(1个月)

4

2 回答 2

2

首先,说到文件系统,在 Windows Server OS 上,磁盘上方有一个内置的缓存层。因此,对于磁盘读取,您可能不会有太大的不同。当然,一次又一次地解析相同的输入并不是一个好习惯,所以解析(tokenized)的xml应该被缓存。

设计需要更多说明:

  1. 是否只有一个 DAL 类实例,在 5 个服务之间共享?或者想法 1 中描述的属性是静态的?

  2. 在想法 2 中:当文件更改时,例如,连接字符串 4 更改(并且其他所有内容保持不变) - 只有服务 4 应该重新加载?

  3. 如果重新加载特定服务 - 它是否会导致与其他(非新鲜)服务的某种不一致?

更新:

我仍然不确定我是否完全理解这种情况,但据我所知,这是我要做的:

DAL 应该为所有与数据相关的操作公开一个接口。

假设它是IDataGateway

现在,每个服务都应该有一个对实现的实例的引用IDataGateway。服务根本不应该知道缓存机制。它只是从接口消费数据。

因此,就类和代码组织而言,所有的缓存都是在服务之外完成的。

现在,缓存层反过来实现IDataGateway了 ,并且还使用了 的非缓存实例IDataGateway。这就是所谓的装饰者模式。非缓存实例将被注入到构造函数中。

现在,我建议每个服务都有自己的缓存实例IDataGateway。它比单例更简单(至少对我而言)。而且由于数据不在服务之间共享,所以我们很酷。但是,如果数据在服务之间共享,则应使用单个实例。

回到这 5 个实例,然后回到 xml 文件。

我们希望在文件更改后对其进行监控,对吗?我们可以很容易地编写自己的文件监视器,或者使用框架自带的,或者我们可以查看 CacheDependency 类的源代码。

最简单的方法是让 5 个监视器监视同一个文件。这对性能的影响不大,因为计时器非常“便宜”。

但是,如果您想减少系统使用的资源,那么您可以使用单个监视器,让它引发它的事件FileChanged或类似的东西。的 5 个缓存实现(这 5 个实例)中的每一个都IDataGateway应该在其构造函数中注入此监视器,并将其自己的事件侦听器连接到FileChanged事件。
一旦触发此事件,所有 5 个缓存实例都IDataGateway将使其内部缓存无效,因此它们应清除其内存中的条目。

在下一次调用时, 的缓存实现IDataGateway将尝试从其内存缓存中获取不存在的数据,但显然不会有任何数据,因此它应该继续在 的非缓存实现中执行相同的方法IDataGateway,并填充它的缓存。

这是我的设计,HTH...

于 2012-11-04T21:23:40.647 回答
0

对我来说,问题归结为谁真正需要了解连接字符串:DAL 还是服务?显然是 DAL。该服务不(或不应该)关心 DAL 正在使用哪种数据存储 - 可能是磁盘上的一堆 CSV(哎呀!)它关心的一切。因此,将连接字符串放在服务中是没有意义的。DAL 需要连接信息,因此 DAL 应该负责查找并缓存它。

于 2012-11-05T01:32:53.767 回答