我正在尝试在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)
{
}
}
有没有更好的方法来解决这个问题,而不是将子容器级联到所有必须使用已解决的依赖性的类?
答案 0 :(得分:0)
以下是使用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)
{
}