【问题标题】:Using Nancy + TinyIoC to inject dependencies via Quartz JobFactory使用 Nancy + TinyIoC 通过 Quartz JobFactory 注入依赖
【发布时间】:2015-02-21 02:34:30
【问题描述】:

所以我正在使用 Nancy + TinyIoC 来运行一个小型 Web 服务。这行得通。现在我需要创建一个 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);
    }
}

【问题讨论】:

    标签: .net quartz.net nancy tinyioc


    【解决方案1】:

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

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

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

    【讨论】:

    • IoC wiki中所说,使用ASP.NET时,需要调用.AsPerRequestSingleton()。 Nancy 引导程序会为我们这样做吗?
    【解决方案2】:

    更新

    对不起。我认为您的 Quartz 工作是在一个单独的项目中,并且您正在使用它来安排对基于 Nancy 的 Web 服务的调用。我知道 Quartz 工作 Nancy 项目中。

    我想你可以无视我原来的答案:-)

    原答案

    您是否指定要将这些依赖项注册为单例?你可以这样做:

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

    我您正在使用 AutoRegister 功能并且您使用的依赖项不是接口或抽象类类型,并且您希望 所有 您的依赖项都是单例,您需要更改 @ TinyIoC 中的 987654323@。

    默认如下:

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

    如您所见,它注册了接口依赖项和抽象类依赖项,以使用SingletonFactory 解析。其他所有内容都使用MultiInstanceFactory 注册。

    然后您可以将其更改为:

    private ObjectFactoryBase GetDefaultObjectFactory(Type registerType, Type registerImplementation)
    {
        return new SingletonFactory(registerType, registerImplementation);
    }
    

    【讨论】:

    • 谢谢。我更新了我的问题,以更好地解释我如何使用 TinyIoC。
    • 啊,明白了。我误解了你的问题。
    【解决方案3】:

    我认为@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(...)
    

    【讨论】:

    • 在多线程环境中公开一个静态的、可变的、有状态的对象通常是个坏主意。如果可以滥用它,就会有人滥用它。
    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2012-03-23
    • 2019-12-03
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2014-09-12
    相关资源
    最近更新 更多