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

时间:2011-07-19 19:06:14

标签: c# dependency-injection ninject ninject-2

所以,假设我有一个界面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容器,以便我可以注入或删除像这样的缓存代理,或者说,记录,或(在这里插入)?

3 个答案:

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