ninject - 防止Ninject绑定(bind)多个接口(interface)时多次调用Initialize

标签 ninject

我们有一个具体的单例服务,它实现了 Ninject.IInitializable和2个接口(interface)。问题是服务 Initialize-methdod 被调用了 2 次,而只需要一次。我们正在使用 .NET 3.5 和 Ninject 2.0.0.0。

Ninject 中是否有一种模式可以防止这种情况发生。这两个接口(interface)都没有实现 Ninject.IInitializable .服务等级是:

public class ConcreteService : IService1, IService2, Ninject.IInitializable
{
    public void Initialize()
    {
        // This is called twice!
    }
}

模块看起来像这样:
public class ServiceModule : NinjectModule
{
    public override void Load()
    {
        this.Singleton<Iservice1, Iservice2, ConcreteService>();
    }
}

其中 Singleton 是一个扩展方法,定义如下:
    public static void Singleton<K, T>(this NinjectModule module) where T : K
    {
        module.Bind<K>().To<T>().InSingletonScope();
    }

    public static void Singleton<K, L, T>(this NinjectModule module) 
        where T : K, L
    {
        Singleton<K, T>(module);
        module.Bind<L>().ToMethod(n => n.Kernel.Get<T>());
    }

当然,我们可以将 bool initialized-member 添加到 ConcreteService 并仅在它为 false 时进行初始化,但这似乎有点 hack。并且它需要在实现两个或多个接口(interface)的每个服务中重复相同的逻辑。

感谢所有的答案!我从他们所有人身上学到了一些东西! (我很难决定哪一个标记是正确的)。

我们最终创建了 IActivable 接口(interface)并扩展了 ninject 内核(它还很好地删除了对 ninject 的代码级依赖,尽管属性仍然存在)。

最佳答案

忍者3

Ninject 3.0 现在在绑定(bind)调用中支持多种泛型类型,您尝试做的事情可以在单个链式语句中轻松完成。

kernel.Bind<IService1, IService2>()
      .To<ConcreteService>()
      .InSingletonScope();

忍者2

您正在设置两个不同的绑定(bind) K=>T 和 L=>T。请求 L 的实例将返回 T 的瞬时实例。请求 K 将返回 T 的单例实例。

在 Ninject 2.0 中,对象作用域是每个服务接口(interface)绑定(bind)到作用域回调的。

当你有
Bind<IFoo>...InSingletonScope();
Bind<IBar>...InSingletonScope();

您正在创建两个不同的范围。

你是说
“绑定(bind)到 IFoo 将解析为返回的相同对象
当 .Get 被调用时。

“绑定(bind)到 IBar 将解析为返回的相同对象
当 .Get 被调用时。

您可以将绑定(bind)链接在一起,但您需要删除 可初始化 因为它会在实例被激活时导致重复初始化:
kernel.Bind<IBoo>()
      .To<Foo>()
      .InSingletonScope();
      .OnActivation(instance=>instance.Initialize());

kernel.Bind<IBaz>()
      .ToMethod( ctx => (IBaz) ctx.Kernel.Get<IBoo>() );

或者
kernel.Bind<Foo>().ToSelf().InSingletonScope()
    .OnActivation(instance=>instance.Initialize());
kernel.Bind<IBaz>().ToMethod( ctx => ctx.Kernel.Get<Foo>() );
kernel.Bind<IBoo>().ToMethod( ctx => ctx.Kernel.Get<Foo>() );

为了让多个接口(interface)解析到同一个单例实例。当我看到这样的情况时,我总是要问,如果你有一个有两个职责的单例,你的对象是不是做得太多了?

关于ninject - 防止Ninject绑定(bind)多个接口(interface)时多次调用Initialize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3043441/

相关文章:

c# - 为 DI 容器创建线程安全的单例包装器

c# - 当我的复合根引用数据层时,我的 DI 架构是否正确?

c# - 安全地对IoC/DI配置进行广泛的更改

c# - 为什么要处理 ASP.NET Web Api Dependency Resolver?

.net - 使用具有自己抽象的 IoC 高级功能

c# - Ninject 字段注入(inject)在构造函数类中不起作用

asp.net-mvc - 模型的依赖注入(inject)

c# - 使用依赖注入(inject)在单元测试中进行模拟

wpf - ViewModel 定位器如何在模块化系统中工作

c# - 开放泛型的 DI 绑定(bind)是一种反模式吗?