我正在使用 DDD 设计 WCF 服务。
我有一个域服务层,它调用存储库来创建域对象。存储库是使用 ADO.Net 而不是 ORM 实现的。数据来自使用存储过程的数据库。在创建一个对象时说一个地址,SP 返回一个状态的 id。 SP 不会将地址表与状态表连接起来。状态由具有 id、abbr 和 name 属性的值对象类 State 表示。当应用程序启动时,状态对象列表可以被缓存(使用 system.runtime.caching.memorycache),因为它是非 volatile 数据。一般来说,我有一个 LookupDataRepository 可以从表中检索所有此类查找数据。现在,AddressRepository 必须从状态 id 填充地址的状态属性。
伪代码:
class AddressRepository : IAddressRepository
{
Address GetAddressById(int id)
{
// call sp and map from data reader
Address addr = new Address(id);
addr.Line = rdr.GetString(1);
addr.State = // what to do ?, ideally LookupCache.GetState(rdr.GetInt32(2))
}
}
class State
{
public int Id;
public string Abbr;
public string Name;
enum StateId {VIC, NSW, WA, SA};
public static State Victoria = // what to do, ideally LookupCache.GetState(StateId.VIC)
}
// then somewhere in address domain model
if(currentState = State.Victroia)
{
// specific logic for Victoria
}
我的问题是把这个缓存放在哪一层?服务,存储库,一个可跨所有层使用的单独程序集。
最佳答案
缓存放在哪里?这取决于。
如果您的场景是将您的 IAddressRepository 注入(inject)多个应用程序服务(我相信您称为 em 域服务),结果将是:
我会在服务层进行缓存。如果感觉更自然,并让您更好地控制要缓存的位置和时间。存储库级别通常是低粒度的。服务层及其方法更接近用例,然后您就知道何时以及缓存什么。
我真的建议编写一个缓存包装器,例如
public class CacheManager : ICacheManager
{
public Address Address
{
get { }
set { }
}
}
它包含对 System.Runtime.Caching.MemoryCache.Default 的静态引用。
它使您的缓存类型安全,并且类型转换仅在包装内完成。您还可以使用注入(inject)的 Mocked ICacheManager 对您的服务进行单元测试。
更高级的方法是使用面向方面的编程和装饰器/拦截器来做到这一点。您在 StackOverFlow https://stackoverflow.com/search?q=AOP+caching 上有大量的好信息
关于caching - 在 DDD 应用程序中,我应该在哪一层实现从数据库中查找数据的缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8060193/