2016-04-12 9 views
3

WebJobs işlev yürütülmesine bağlanmanın bir yolu var mı, bu yüzden işlev başına bir kapsamımız olabilir mi? Böyle bir şey:Bağımlılık Enjeksiyonu Dinamik işlev kapsamındaki DbContext için WebJobs ile Nesne Oluşturma

kernel.Bind<MyDbContext>().ToSelf().InWebJobFunctionScope();

Ben Ninject dan InScope() kullanmak istiyorum ama statik HttpContext.Current ama WebJob anda çalışan için benzer bir şey bulabileceği bilmiyorum.

+0

Merhaba JS, ben bir sorunu açtım https://github.com/Azure/azure-webjobs-sdk-extensions/issue/39 ancak InThreadScope'u kullanabilir misiniz? – Thomas

+0

@Thomas Async/await desenini kullanırken iş parçacığı alanının yanlış davranmaya başlayacağını düşünürdüm. Her statik işlev için BeginBlock kullanmayı denedim ve her şey başarısız olmaya başladı. Bu yüzden ben şimdi bir içerik oluşturmak için içerik nuget paketiyle bir CreateNameScope ile InNamedScope kullanıyorum db içeriği için çalışan bir şey ... Kesinlikle acı verici ve şüphesiz ben isim kapsamı böyle çalışmak gerekiyordu. – jsgoupil

cevap

7

Bunun eski olduğunu biliyorum, ama aynı dramalarım vardı. Web işlerinin daha yeni bir sürümünden bu yana örnekler ve örnek yöntemleri kullanabilir ve özel IJobActivator örneklerini iletebilirsiniz. Şaşırtıcı derecede kolay.

Ninject ile mükemmel çalışır. Ben ...

public class MyJobActivator : IJobActivator 
{ 
    protected readonly IKernel _kernel; 

    public MyJobActivator(IKernel kernel) 
    { 
     _kernel = kernel; 
    } 

    public T CreateInstance<T>() 
    { 
     return _kernel.Get<T>(); 
    } 
} 


public class MyBindings : NinjectModule 
{ 
    public override void Load() 
    {  
     Bind(typeof(DbContext)).To(typeof(MyEntities)); 
    } 
} 

class Program 
{   
    static void Main() 
    { 
     using (IKernel kernel = new StandardKernel(new MyBindings())) 
     { 
      var jobHostConfiguration = new JobHostConfiguration 
      { 
       JobActivator = new MyJobActivator(kernel) 
      }; 

      var host = new JobHost(jobHostConfiguration); 

      // The following code will invoke a function called ManualTrigger and 
      // pass in data (value in this case) to the function 
      host.Call(typeof(Reminders).GetMethod("ManualTrigger"), new { value = 20 }); 
     } 
    } 
} 


public class Reminders 
{ 
    private readonly IMyService _myService; 

    public Reminders(IMyService myService) 
    { 
     _myService = myService; 
    } 

    // This function will be triggered based on the schedule you have set for this WebJob 
    // This function will enqueue a message on an Azure Queue called queue 
    [NoAutomaticTrigger] 
    public async Task ManualTrigger(TextWriter log, int value, TextWriter logger) 
    { 
     try 
     { 
      // process the notification request 
      await _myService.FindAndSendReminders(); 
      await _myService.SaveChangesAsync(); 
     } 
     catch (Exception e) 
     { 
      logger.WriteLine(e.Message); 
      Console.WriteLine(e.Message); 
      throw; 
     } 
    } 
} 

EDIT herhangi Ninject örnekleri görülen, bu yüzden henüz: Yukarıdakilere ek olarak Geçenlerde gördüğüm sen host.Call (typeof (Hatırlatmalar) kullanmaya gerek olmayabilir öğrendim. . Bu, aşağıda resimli edilir GetMethod ("ManualTrigger"), en azından sürekli bir web işleri için.

Siz sadece Fonksiyonlar sınıf dışı statik yapmak ve enjeksiyon için bir kurucu ekleyin ve ardından işleme yöntemi olmayan statik olun.

public class Program 
{   
    static void Main() 
    { 
     using (IKernel kernel = new StandardKernel(new MyBindings())) 
     { 
      var jobHostConfiguration = new JobHostConfiguration 
      { 
       JobActivator = new MyJobActivator(kernel) 
      }; 

      var host = new JobHost(jobHostConfiguration); 

      // The following code ensures that the WebJob will be running continuously 
      host.RunAndBlock(); 
     } 
    } 
} 


public class Functions 
{ 
    private readonly IMyService _myService; 

    public Functions(IMyService myService) 
    { 
     _myService = myService; 
    }   

    public async Task ProcessReminders([QueueTrigger("reminder-requests")] string notificationMessage, TextWriter logger) 
    { 
     try 
     { 
      // process the notification request 
      await _myService.FindAndSendReminders(); 
      await _myService.SaveChangesAsync(); 
     } 
     catch (Exception e) 
     { 
      logger.WriteLine(e.Message); 
      Console.WriteLine(e.Message); 
      throw; 
     } 
    } 
} 

Orijinal kodumu, Autofac için bulduğum bir makaleden uyarladım

http://www.jerriepelser.com/blog/dedependency-injection-with-autofac-and-webjobs

da

Dependency injection using Azure WebJobs SDK?

Bkz Ve sürekli webjobs için

http://www.ryansouthgate.com/2016/05/10/azure-webjobs-and-dependency-injection/

+0

Bazı nedenlerle, bunun eşzamanlılık ile çalışmadığına inanmak için bir nedenim vardı ve/veya GetMethod() hilesiyle çağrı yaparken çalışmadı. @Thomas, bunun uzun zaman önce aradığımız şeyi kapsadığını düşünüyor musunuz: P? – jsgoupil

+0

jsgoupil Getmethod kullanımını gerektirmeyen sürekli webjobs için cevabımı güncelledim. Umarım yardımcı olur. – Troyka

+0

@Troyka Tetiklenen webjobs içindeki Entity Framework DbContext nesnelerinin yaşam döngüsü için fikriniz nedir? Açıkçası, webjob süreci sürekli canlıdır, belki de DbContext'i bir singleton'a dahil etmem gerektiğini söyler, fakat diğer taraftan işlevler her bir mesajda yer alır, böylece her bir fonksiyonun yürütülmesi için DbContext'i kullanabilirdim. Ne önerirsiniz? – Howiecamp

İlgili konular