Bre*_*ner 2 c# singleton dependency-injection thread-safety
我正在写一个装饰器来实现缓存.该对象将由我的DI容器注册为单例.因为我知道我将对象注册为单例,所以表示我的缓存的字段不是静态的.我不确定这是否是最佳做法,但我试图不惜一切代价避免锁定.我的缓存是懒惰的初始化,只有一次昂贵/运行.我的问题是我需要担心运行缓存初始化逻辑的多个线程吗?我的直觉告诉我"是的,我确实需要担心",但我听到其他开发人员说"如果它不是静止的话就没有锁定点".
//SimpleInjector DI Container configuration
public static class Bootstrapper
{
public static void ConfigureContainer(Container container)
{
container.Register<IQueryHandler<GetFoos, Foo[]>, GetFoosHandler>(Lifestyle.Singleton);
container.RegisterDecorator<IQueryHandler<GetFoos, Foo[]>, GetFoosCachingHandler>(Lifestyle.Singleton);
}
}
public class Foo
{
public int Id;
public string FooTypeCode;
public string Name;
}
public class GetFoos : IQuery<Foo[]>
{
public string FooTypeCode;
}
public class GetFoosCachingHandler : IQueryHandler<GetFoos, Foo[]>
{
private Lazy<Dictionary<string, Foo[]>> _cache;
private readonly IQueryHandler<GetFoos, Foo[]> _queryHandler;
public GetFoosCachingHandler(IQueryHandler<GetFoos, Foo[]> queryHandler)
{
_queryHandler = queryHandler;
_cache = new Lazy<Dictionary<string, Foo[]>>(() =>
{
//expensive and run only once operation e.g. subscribe to bus for cache invalid messages and reset cache
return new Dictionary<string, Foo[]>();
});
}
public Foo[] Handle(GetFoos query)
{
var cache = _cache.Value;
if (!cache.ContainsKey(query.FooTypeCode))
{
cache[query.FooTypeCode] = _queryHandler.Handle(new GetFoos { FooTypeCode = query.FooTypeCode });
}
return cache[query.FooTypeCode];
}
}
Run Code Online (Sandbox Code Playgroud)