sof*_*eda 2 caching domain-driven-design repository
我正在使用DDD设计WCF服务.我有一个域服务层,它调用存储库来创建域对象.存储库使用ADO.Net而不是ORM实现.数据来自使用存储过程的DB.在创建对象时,说一个地址,SP返回一个状态的id.SP不会将地址表与状态表连接.状态由具有id,abbr和name属性的值对象类State表示.当应用程序启动时,状态对象列表可以缓存(使用system.runtime.caching.memorycache),因为它是非易失性数据.通常我有一个LookupDataRepository,它可以从表中检索所有这些查找数据.现在,AddressRepository必须从状态id填充地址的State属性.
伪代码:
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
}
Run Code Online (Sandbox Code Playgroud)
我的问题是放置这个缓存的哪一层?服务,存储库,跨所有层的单独程序集.
哪里放Cache?这取决于.如果你的情况是你将IAddressRepository注入几个应用程序服务(我相信你称之为域Domain服务),结果将是:
我会去服务层进行缓存.如果感觉更自然,并让您更好地控制要缓存的位置和时间.存储库级别通常是低粒度的.服务层及其方法更接近用例,然后您就知道何时以及要缓存什么.
我真的建议你写一个缓存包装器
public class CacheManager : ICacheManager
{
public Address Address
{
get { }
set { }
}
}
Run Code Online (Sandbox Code Playgroud)
它包含对System.Runtime.Caching.MemoryCache.Default的静态引用.
它使您的缓存类型安全和转换只在内部包装器中完成.您还可以使用注入的Mocked ICacheManager对您的服务进行单元测试.
更高级的方法是使用面向方面编程和装饰器/拦截器来实现这一点.StackOverFlow上有大量有用的信息https://stackoverflow.com/search?q=AOP+caching