Azure Web jobs - Unity - 如何将作用域依赖项注入其他类



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

// 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)
    {
    }
}

有没有更好的方法来解决此问题,而不是将子容器级联到必须使用已解析的 depencency 的所有类?

下面是

使用Microsoft.Extensions.DependencyInjection而不是unity的示例:

// 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)
{
}

最新更新