依赖注入:如何为包装配置接口绑定

本文关键字:包装 配置 接口 绑定 注入 依赖 | 更新日期: 2023-09-27 18:02:53

那么,假设我有一个接口IThingFactory:

public interface IThingFactory
{
    Thing GetThing(int thingId);
}

现在,假设我有一个从数据库中检索Thing s的具体实现。现在,假设我有一个具体的实现,它包装了一个现有的IThingFactory,并在到达包装的IThingFactory之前检查Thing是否存在于内存缓存中。比如:

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容器,这样我就可以注入或删除这样的缓存代理,或者,说,做日志记录的东西,或者(插入这里)?

依赖注入:如何为包装配置接口绑定

你可以这样做:

Bind<IThingFactory> ().To<DefaultThingFactory> ().WhenInjectedInto<CachedThingFactory> ();
Bind<IThingFactory> ().To<CachedThingFactory> ();

这将使消费者不需要指定name属性,并且仍然相对容易进一步增强。如果您以后想为日志添加一个额外的"decorator"层,您可以这样做:

Bind<IThingFactory> ().To<DefaultThingFactory> ().WhenInjectedInto<LoggingThingFactory> ();
Bind<IThingFactory> ().To<LoggingThingFactory> ().WhenInjectedInto<CachedThingFactory> ();
Bind<IThingFactory> ().To<CachedThingFactory> ();

不是最漂亮的,但是很好用。

使用DI框架的好处之一是您不必做这些事情。Ninject有各种作用域,可以用来指定对象的生命周期。它会帮你处理缓存之类的。

阅读更多:http://kohari.org/2009/03/06/cache-and-collect-lifecycle-management-in-ninject-20/

我想你是在搜索命名绑定,文档在这里:

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;
}