所以,假设我有一个界面IThingFactory
:
public interface IThingFactory
{
Thing GetThing(int thingId);
}
现在,假设我有一个从数据库中检索Thing
的具体实现。现在,我们还说我有一个具体的实现,它包装了一个现有的IThingFactory
,并在命中包装Thing
之前检查了IThingFactory
在内存缓存中的存在。类似的东西:
public class CachedThingFactory : IThingFactory
{
private IThingFactory _wrapped;
private Dictionary<int, Thing> _cachedThings;
public CachedThingFactory(IThingFactory wrapped)
{
this._wrapped = wrapped;
_cachedThings = new Dictionary<int,Thing>();
}
public Thing GetThing(int thingId)
{
Thing x;
if(_cachedThings.TryGetValue(thingId, out x))
return x;
x = _wrapped.GetThing(thingId);
_cachedThings[thingId] = x;
return x;
}
}
我如何使用依赖注入来处理这样的场景,例如Ninject,以便我可以配置DI容器,以便我可以注入或删除像这样的缓存代理,或者说,记录,或(在这里插入)?
答案 0 :(得分:5)
您可以采取以下措施:
Bind<IThingFactory> ().To<DefaultThingFactory> ().WhenInjectedInto<CachedThingFactory> ();
Bind<IThingFactory> ().To<CachedThingFactory> ();
这将让消费者不需要指定名称属性,并且仍然相对容易进一步增强。如果您以后想要为记录添加额外的“装饰器”图层,则可以执行以下操作:
Bind<IThingFactory> ().To<DefaultThingFactory> ().WhenInjectedInto<LoggingThingFactory> ();
Bind<IThingFactory> ().To<LoggingThingFactory> ().WhenInjectedInto<CachedThingFactory> ();
Bind<IThingFactory> ().To<CachedThingFactory> ();
不是最漂亮的,但它确实有效。
答案 1 :(得分:2)
DI框架的一个好处是你不必做这些事情。 Ninject具有各种范围,可用于指定对象的生命周期。它会为你处理缓存和东西。
在此处阅读更多内容:http://kohari.org/2009/03/06/cache-and-collect-lifecycle-management-in-ninject-20/
答案 2 :(得分:2)
我想你正在寻找命名绑定,记录在这里:
https://github.com/ninject/ninject/wiki/Contextual-Binding
Bind<IThingFactory>().To<CachedThingFactory>().Named("TheCachedThing");
Bind<IThingFactory>().To<DefaultThingFactory >().Named("ThePureThing");
然后
public CachedThingFactory([Named("ThePureThing")] IThingFactory wrapped)
{
this._wrapped = wrapped;
_cachedThings = new Dictionary<int,Thing>();
}
以及CachedThingFactory的消费者
public ThingFactoryConsumer([Named("TheCachedThing")] IThingFactory thingFactory)
{
_thingFactory = thingFactory;
}