2017-02-13 70 views
2

我有一系列的類,我來處理,看上去像這樣WebJobs:WebJob依賴注入綁定到泛型類

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(); 
    } 
} 

但最近我想「泛化」的工作,所以,他們不依賴於特定的DbContexts。我試圖用這樣的模式:

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控制檯應用程序啓動正常,但它抱怨:

找不到工作職能。嘗試使你的工作類和方法 公開。

是不是可以將作業綁定到泛型類的實例?

回答

2

根據你的描述,我已經測試了這個問題,在我的身邊,並按如下,我可以重現這個問題:

後我檢查Azure WebJobs SDK源代碼的混帳,我發現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實例。此外,您可以添加您的反饋here