我可以使用Ninject来实例化不依赖的单件服务吗?

时间:2015-07-16 03:52:24

标签: c# singleton ninject

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

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

我可以手动实例化它,明确地提供它与kernel.Get的依赖关系,但感觉我不应该这样做。

即使没有别的东西依赖它,我是否可以在单例范围中急切地实例化Ninject类

2 个答案:

答案 0 :(得分:3)

如果你没有要求它自己实例化,你不能拥有ninject实例化的东西。 简单的方法是让ninject在组合根处实例化事物:

dupe

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

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>();

为什么

Ninject不像其他一些容器(例如Autofac)而不是&#34;内置&#34;分阶段。没有先创建绑定,然后创建内核以使用它们的概念。以下是完全合法的:

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

所以ninject可能无法知道何时你想要实例化单例。使用autofac it's clear and easy

kernel.Bind<IFoo>()...
kernel.Get<IFoo>()...
kernel.Bind<IBar>()...
kernel.Get<IBar>()...

答案 1 :(得分:1)

来自Java的Guice,我非常想念渴望的单例模式。它们在模块充当插件的场景中很有用。如果您想象服务是由配置中指定的模块组装而成的,那么您可能会遇到一个问题,那就是还要尝试指定启动应用程序时需要自动实例化该模块的内容。

对我来说,模块是在其中定义应用程序的组成部分,将急切的单身人士分隔到代码中的另一个位置会感觉比较笨拙且不直观。

无论如何,我已经能够非常轻松地将其实现为Ninject之上的一层,这是代码:

public static class EagerSingleton
{
    public static IBindingNamedWithOrOnSyntax<T> AsEagerSingleton<T>(this IBindingInSyntax<T> binding)
    {
        var r = binding.InSingletonScope();

        binding.Kernel.Bind<IEagerSingleton>().To<EagerSingleton<T>>().InSingletonScope();

        return r;
    }
}

public interface IEagerSingleton { }

public class EagerSingleton<TComponent> : IEagerSingleton
{
    public EagerSingleton(TComponent component)
    {
        // do nothing. DI created the component for this constructor.
    }
}

public class EagerSingletonSvc
{
    public EagerSingletonSvc(IEagerSingleton[] singletons)
    {
        // do nothing. DI created all the singletons for this constructor.
    }
}

创建内核后,添加一行:

kernel.Get<EagerSingletonSvc>(); // activate all eager singletons

您可以在这样的模块中使用它:

Bind<UnhandledExceptionHandlerSvc>().ToSelf().AsEagerSingleton();
相关问题