Azure webjobs - Unity - 如何将范围内的依赖项注入其他类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Azure webjobs - Unity - 如何将范围内的依赖项注入其他类相关的知识,希望对你有一定的参考价值。

我试图在Azure webJob中注入依赖项。我目前正在使用IJobActivator来创建和解析统一容器。

// Job setup
static void Main()
{
    var config = new JobHostConfiguration();
    config.JobActivator = new JobActivationHandler();

    var host = new JobHost(config);
    host.RunAndBlock();
}

我目前正在传递容器本身,以创建子容器,并解决作业范围中的依赖项。

internal class JobActivationHandler : IJobActivator
{
    private IUnityContainer container;

    public JobActivationHandler()
    {
        container = new UnityContainer();

        container.RegisterType<IDependency, Dependency>();
        // I am passing the container itself, to register job specific 
        // dependencies, pls see the webjob implementation.
        container.RegisterInstance<IUnityContainer>(container);
    }

    public T CreateInstance<T>()
    {
        return container.Resolve<T>();
    }
}

// WebJob
 private readonly IUnityContainer jobContainerInstance;

    public ProcessDataJob(IUnityContainer unityContainer)
    {
      // Create a child container for this job instance, 
      // so that the depencies are scoped for current job.
        this.jobContainerInstance = unityContainer.CreateChildContainer();
    }

     public async Task ProcessDataJob(
        [QueueTrigger("%Queue:DataQueue%")] DataObject dataObject ,
        [Blob("%Blob:LogOutput%/{TenantId}/{JobId}.txt")] TextWriter blobLogOutput)
    {
          /* Here i am creating a log writer or other service, 
          that are job instance specific, and this dependency 
          should be injected to other classes.
          This service is instance specific, so i cannot instantiate it in 
          the root container*/
         logWriter = CreateLogger(dataObject);
         jobContainerInstance.RegisterInstance<ILogWriter>(logWriter);

         /* The only way i can inject this dependency is to resolve a class 
         out of this child container itself. */
            var classB = jobContainerInstance.Resolve<ClassB>()
    }


// The dependency ILogWriter is properly resolved. 
// But i need to pass on the container as well, if i need this dependency to 
// be injected in class C
ClassB
{
   public ClassB(IUnityContainer unityContainerInstance, ILogWriter logWriter)
    {
       var classC = unityContainerInstance.Resolve<ClassC>();
    }
}

ClassC
{
   public ClassC(IUnityContainer unityContainerInstance, ILogWriter logWriter)
    {

    }
}

有没有更好的方法来解决这个问题,而不是将子容器级联到所有必须使用已解决的依赖性的类?

答案

这是使用Microsoft.Extensions.DependencyInjection而不是统一的示例:

// Job setup
static void Main()
{
    var services = new ServiceCollection();
    // Register your services here
    services.AddSingleton<ClassB>();
    services.AddScoped<ClassC>();

    var serviceProvider = services.BuildServiceProvider();
    var config = new JobHostConfiguration
    {
        JobActivator = new JobServiceProviderActivator(serviceProvider)
    };

    var host = new JobHost(config);
    host.RunAndBlock();
}

这是服务提供商:

public class JobServiceProviderActivator : IJobActivator
{   
    private readonly IServiceProvider provider;

    public JobServiceProviderActivator(IServiceProvider provider)
    {
        this.provider = provider;
    }

    public T CreateInstance<T>()
    {
        return provider.GetService<T>();
    }
}

注册后,您可以将您的类注入到作业类构造函数中:

public ProcessDataJob(ClassB classB)
{
}

以上是关于Azure webjobs - Unity - 如何将范围内的依赖项注入其他类的主要内容,如果未能解决你的问题,请参考以下文章

使用 azure webjobs 我如何为计划任务传递参数

Azure 触发的 Webjob - 检测 webjob 何时停止

Azure 服务总线:Microsoft.Azure.WebJobs.Script.HostDisposedException:主机已释放,无法使用

无法调试 Azure webjobs - webjob 进程未显示在“附加到进程”对话框中

如何扩展 Azure Webjobs

Laravel 队列和 Azure WebJob