gpt4 book ai didi

c# - Hangfire 依赖注入(inject)生命周期范围

转载 作者:IT王子 更新时间:2023-10-29 04:48:31 26 4
gpt4 key购买 nike

我正在重写整个问题,因为我知道原因,但仍然需要一个解决方案:

我在 Hangfire 中有一个循环作业,每分钟运行一次并检查数据库,可能会更新一些东西,然后退出。

我将我的 dbcontext 注入(inject)到包含作业方法的类中。我注册此 dbcontext 以使用以下命令进行注入(inject)

builder.RegisterType<ApplicationDbContext>().As<ApplicationDbContext>().InstancePerLifetimeScope();

但是,似乎 Hangfire 并没有在每次作业运行时创建一个单独的生命周期范围,因为构造函数只被调用一次,尽管作业方法每分钟调用一次。

这给我带来了问题。如果用户更新数据库中的某些值(dbcontext 被注入(inject)到其他地方,并用于更新值),仍在使用的上下文 Hangfire 开始返回已经更改的过时值。

最佳答案

Hangfire 目前为每个 Worker 使用 JobActivator 的共享实例,它们使用以下方法来解决依赖关系:

    public override object ActivateJob(Type jobType)

计划为Milestone 2.0.0在这个方法中添加一个JobActivationContext .

目前,还没有办法说明哪个作业的依赖关系得到了解决。我能想到的解决此问题的唯一方法是利用作业在不同线程上串行运行这一事实(我不知道 AutoFac,所以我以 Unity 为例)。

您可以创建一个 JobActivator 来为每个线程存储单独的作用域:

public class UnityJobActivator : JobActivator
{
[ThreadStatic]
private static IUnityContainer childContainer;

public UnityJobActivator(IUnityContainer container)
{
// Register dependencies
container.RegisterType<MyService>(new HierarchicalLifetimeManager());

Container = container;
}

public IUnityContainer Container { get; set; }

public override object ActivateJob(Type jobType)
{
return childContainer.Resolve(jobType);
}

public void CreateChildContainer()
{
childContainer = Container.CreateChildContainer();
}

public void DisposeChildContainer()
{
childContainer.Dispose();
childContainer = null;
}
}

使用带有 IServerFilter 实现的 JobFilter 为每个作业(线程)设置此范围:

public class ChildContainerPerJobFilterAttribute : JobFilterAttribute, IServerFilter
{
public ChildContainerPerJobFilterAttribute(UnityJobActivator unityJobActivator)
{
UnityJobActivator = unityJobActivator;
}

public UnityJobActivator UnityJobActivator { get; set; }

public void OnPerformed(PerformedContext filterContext)
{
UnityJobActivator.DisposeChildContainer();
}

public void OnPerforming(PerformingContext filterContext)
{
UnityJobActivator.CreateChildContainer();
}
}

最后设置你的 DI:

UnityJobActivator unityJobActivator = new UnityJobActivator(new UnityContainer());
JobActivator.Current = unityJobActivator;

GlobalJobFilters.Filters.Add(new ChildContainerPerJobFilterAttribute(unityJobActivator));

关于c# - Hangfire 依赖注入(inject)生命周期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27961210/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com