我有一个包含几个不同功能的Azure WebJob。
这些函数需要通过Ninject注入一些服务(使用构造函数注入)。由于标准的JobActivator --负责示例化作业类的类--通过调用无参数构造函数来创建作业类,所以我不能使用它。
为了做到这一点,我创建了一个实现IJobActivator
接口的类-由WebJobs SDK提供,类似于this walkthrough。
由于我需要这个注入的服务在函数完成之前一直处于活动状态(并且似乎容器没有办法知道函数何时完成),我遵循了以下解决方案:https://blog.tech-fellow.net/2017/04/12/disposable-dependency-for-azure-webjob/
该文章引用了不同的容器(StructureMap),但概念是相同的:
- 在
JobActivator
中创建一个嵌套容器 - 该嵌套容器被传递给包含该函数的类
- 包含该函数的类实现
IDisposable
接口 - 在
Dispose()
方法中,释放子容器
据我所知,Ninject不支持嵌套容器,即使我发现this extension似乎做了类似的事情。
所以我会这么做
1.在WebJob中创建一个主内核,并将其传递给JobActivator
1.在JobActivator
的CreateInstance
中,我从原始的子内核创建了一个新的子内核
1.我将该子内核设置到作业的类示例中
1.在Dispose
方法中,我将释放子内核
问题:
- 你怎么看待这种创建子内核的方法?是你会避免的吗?
- 通过检查子内核扩展的源代码,在我看来,子内核的
Dispose
方法没有特别的变化。如果我说在子内核上调用Dispose()
,不会处理主内核,对吗? - 请确认一旦Ninject内核il被释放(通过调用它的
Dispose()
方法),那么所有创建的示例-即使是那些InTransientScope-也会被释放?
1条答案
按热度按时间oknwwptz1#
事实证明,在
JobActivator
Activate()
函数中创建ChildKernel
是一个非常缓慢的过程。我的分析表明,如果
JobActivator
上的并发性很高,那么启动新的ChildKernel并激活作业的过程将花费相当长的时间。在我的例子中,它比真实的的作业执行时间大一个数量级,所以它是完全不可接受的。我所做的是在
JobActivator
中序列化作业创建的过程,方法是将需要作用于特定函数执行的服务的范围限定到特定的ExecutionContext
(我创建的类)。我所有的工作都实现了
IDisposable
接口。在相应的Dispose()
方法中,我将处理特定的ExecutionContext
,让Ninject Kernel(Program.cs中唯一示例化的)最终释放作用域为该对象的服务。