[英]WebJob Dependency Injection Binding to Generic Class
我有一系列用於處理 WebJobs 的類,它們看起來像這樣:
public class EnvelopeSalutationJob : BatchJob
{
public EnvelopeSalutationJob( StringWriter swLogger )
: base( swLogger, "Envelope Salutation Job" )
{
}
[ Singleton() ]
public async Task ProcessMessage(
[ QueueTrigger( "%" + nameof( ContainerQueueConstants.EnvelopeSalutation ) + "%" ) ] EnvelopeSalutationMessage msg,
TextWriter azureLogWriter
)
{
PhaseNames.SetNames( "Processing Homes", "Job Completed" );
await ExecuteFromMessage( msg, azureLogWriter, Launch );
}
}
這些使用 AutoFac 作為 DI 框架效果很好,配置如下所示:
public static class ContainerConfig
{
public static IContainer GetContainer()
{
var builder = new ContainerBuilder();
// per job
builder.RegisterType<StringWriter>();
// jobs
builder.RegisterType<EnvelopeSalutationJob>();
return builder.Build();
}
}
但最近我想“通用化”這些工作,這樣它們就不會與特定的 DbContext 綁定。 我嘗試使用這樣的模式:
public class EnvelopeSalutationJob<TContext, TUser>
: BatchJob<TContext, TUser>
where TContext : IdentityDbContext<TUser>, ICampaignContext, new()
where TUser : IdentityUser, INamedUser
{
public EnvelopeSalutationJob( StringWriter swLogger )
: base( swLogger, "Envelope Salutation Job" )
{
}
[ Singleton() ]
public async Task ProcessMessage(
[ QueueTrigger( "%" + nameof( ContainerQueueConstants.EnvelopeSalutation ) + "%" ) ] EnvelopeSalutationMessage msg,
TextWriter azureLogWriter
)
{
PhaseNames.SetNames( "Processing Homes", "Job Completed" );
await ExecuteFromMessage( msg, azureLogWriter, Launch );
}
}
AutoFac 配置更改為:
public static class ContainerConfig
{
public static IContainer GetContainer()
{
var builder = new ContainerBuilder();
// per job
builder.RegisterType<StringWriter>();
// jobs
builder.RegisterType<EnvelopeSalutationJob<ConnellJobContext, ConnellUser>>();
return builder.Build();
}
}
不幸的是,這行不通。 WebJobs 控制台應用程序啟動正常,但它抱怨:
沒有找到工作職能。 嘗試公開您的作業類和方法。
是否無法將作業綁定到泛型類的實例?
根據你的描述,我已經在我這邊測試過這個問題,我可以按如下方式重現這個問題:
之后我檢查Azure的WebJobs SDK上的Git源代碼,我發現DefaultTypeLocator.cs將使用IsJobClass
是調用Type.ContainsGenericParameters到過濾器類型如下:
public static bool IsJobClass(Type type)
{
if (type == null)
{
return false;
}
return type.IsClass
// For C# static keyword classes, IsAbstract and IsSealed both return true. Include C# static keyword
// classes but not C# abstract keyword classes.
&& (!type.IsAbstract || type.IsSealed)
// We only consider public top-level classes as job classes. IsPublic returns false for nested classes,
// regardless of visibility modifiers.
&& type.IsPublic
&& !type.ContainsGenericParameters;
}
此外, FunctionIndexer.cs將使用IsJobMethod
來過濾方法,如下所示:
public bool IsJobMethod(MethodInfo method)
{
if (method.ContainsGenericParameters)
{
return false;
}
if (method.GetCustomAttributesData().Any(HasJobAttribute))
{
return true;
}
if (method.GetParameters().Length == 0)
{
return false;
}
if (method.GetParameters().Any(p => p.GetCustomAttributesData().Any(HasJobAttribute)))
{
return true;
}
return false;
}
根據我的理解,Azure WebJobs SDK 目前不支持將作業綁定到泛型類的實例。 您可以定義您的BaseDbContext
並利用構造函數依賴注入來初始化您的DbContext
實例。 此外,您可以在此處添加您的反饋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.