2

所以我使用 Nancy + TinyIoC 来运行一个小型网络服务。这行得通。现在我需要创建一个 Quartz 作业,它需要一些相同的依赖项,理想情况下我想使用 Nancy 的 TinyIoC 来注入这些,如Quartz Tutorial中所述。

我发现了一个使用 Windsor 的示例,他们在其中直接访问 IoC 容器,但根据此处提出的类似问题,在 Nancy 看来,这是粗略且不必要的。

那么我的问题必须是,这样做的正确方法是什么?我的 JobFactory 的代码如下所示:

public class MyJobFactory : IJobFactory
{
    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return (IJob) TinyIoCContainer.Current.Resolve(bundle.JobDetail.JobType);
    }
}

但这不会返回具有正确注入实例的作业,而是返回具有依赖项的新实例的作业。(应该是单例,这让我相信 TinyIoCContainer.Current 返回的 TinyIoCContainer 与 Nancy 使用的容器不同)。

更新
我正在通过 Nancy Bootstrapper 设置 IoC 容器:

public class MyBootStrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        var push = new PushService();
        // object initialization and Event Registration snipped
        container.Register(cp);
    }
}
4

3 回答 3

5

让我相信 TinyIoCContainer.Current 返回的 TinyIoCContainer 与 Nancy 使用的容器不同)。

得到它:-) .Current 是一个静态实例,我们可能应该从 tinyioc.cs 文件的 Nancy 版本中删除它 - 它与引导程序使用的实例不同。

如果您绝对必须使用服务位置,并且无法只使用构造函数注入,则可以在引导程序中覆盖 GetApplicationContainer 方法并返回 .Current 实例,以便 Nancy 使用它。默认情况下我们不使用它,因为我们不建议这样做

于 2012-10-12T13:37:32.100 回答
0

Update

I'm sorry. I thought your Quartz job was in a separate project and that you were using it to schedule calls to your Nancy-based webservice. I know understand the Quartz job is inside the Nancy project.

I think you can disregard my original answer :-)

Original answer

Do you specify you want those dependencies registered as a singleton? You can do it like this:

TinyIoCContainer.Current.Register<SomeType>().AsSingleton();

I you are using the AutoRegister functionality and the dependencies you use aren't interfaces or abstract class types and you want all your dependencies to be singletons, you will need to the change the GetDefaultObjectFactory in TinyIoC.

The default looks like this:

private ObjectFactoryBase GetDefaultObjectFactory(Type registerType, Type registerImplementation)
{
    //#if NETFX_CORE
    //if (registerType.GetTypeInfo().IsInterface() || registerType.GetTypeInfo().IsAbstract())
    //#else
    if (registerType.IsInterface() || registerType.IsAbstract())
    //#endif
        return new SingletonFactory(registerType, registerImplementation);

    return new MultiInstanceFactory(registerType, registerImplementation);
}

As you can see it registers interface dependencies and abstract class dependencies to be resolved using a SingletonFactory. Everything else is registered using a MultiInstanceFactory.

You can then change it to this:

private ObjectFactoryBase GetDefaultObjectFactory(Type registerType, Type registerImplementation)
{
    return new SingletonFactory(registerType, registerImplementation);
}
于 2012-10-12T12:15:52.060 回答
0

我认为@Steven 的信息很棒。然后,我得到了另一个解决方案,将 Bootstrap IoC 公开为静态属性。

public class Bootstrapper : DefaultNancyBootstrapper
{
    public static TinyIoCContainer Container { get; private set; }

    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        Container = container;
    }
}

使用时...

Bootstrapper.Container.Resolve(...)
于 2015-02-20T18:34:30.967 回答