我可以使用Ninject实例化不依赖任何内容的单例服务吗?

Mat*_*hew 5 c# singleton ninject

我的asp.net mvc应用程序中有一些服务,它们侦听AMQP消息并调用方法。

没有控制器依赖于此,因此不会单独实例化它。

我可以手动实例化它,显式地提供它的依赖关系,kernel.Get但感觉我不必这样做。

即使没有其他依赖它,我也可以在单例范围内急于使Ninject实例化类吗?

Bat*_*nit 4

如果您不要求 ninject 自己实例化某些内容,则无法让 ninject 实例化某些内容。简单的方法是要求 ninject 在组合根实例化事物:

var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies()); // loads all modules in assemlby
//...
// resolution root completely configured

kernel.Resolve<IFooSingleton>();
kernel.Resolve<IBarSIngleton>();
Run Code Online (Sandbox Code Playgroud)

实际上,还有一种替代方案,它不一样,但可以用来实现类似的效果。它要求至少有一个其他服务足够快地实例化:Ninject.Extensions.DependencyCreation。它的工作原理如下:

kernel.Bind<string>().ToConstant("hello");

kernel.Bind<ISingletonDependency>().To<SingletonDependency>()
    .InSingletonScope();
kernel.DefineDependency<string, ISingletonDependency>();

kernel.Get<string>();
// when asking for a string for the first time
// ISingletonDependency will be instantiated.
// of course you can use any other type instead of string
Run Code Online (Sandbox Code Playgroud)

为什么

Ninject 与其他一些容器(例如 Autofac)不同,不是分阶段“构建”的。不存在首先创建绑定,然后创建内核来使用它们的概念。以下是完全合法的:

kernel.Bind<IFoo>()...
kernel.Get<IFoo>()...
kernel.Bind<IBar>()...
kernel.Get<IBar>()...
Run Code Online (Sandbox Code Playgroud)

所以 ninject 不可能知道你什么时候想要实例化单例。使用 autofac就变得清晰简单

var containerBuilder = new ContainerBuilder();

containerBuilder
    .RegisterType<Foo>()
    .AutoActivate();

var container = containerBuilder.Build(); // now
Run Code Online (Sandbox Code Playgroud)