ASP.NET कोर में क्वार्ट्ज

परिचय


मुझे पता है कि इस विषय पर बहुत सारे लेख और कुछ प्रकार के ट्यूटोरियल हैं, मैं आधिकारिक दस्तावेज के बारे में भी बात नहीं कर रहा हूं, लेकिन जब मैं अपने नवीनतम प्रोजेक्ट पर काम कर रहा हूं तो एक बहुत ही दिलचस्प समस्या आई है, जिसका बहुत अधिक उल्लेख नहीं किया गया है। आज हम एक ASP.NET कोर परियोजना में निर्भरता इंजेक्शन और क्वार्ट्ज का उपयोग करने की समस्या के बारे में बात करेंगे।

यह सब इस तथ्य के साथ शुरू हुआ कि मैंने नहीं सोचा था कि कोई समस्या उत्पन्न हो सकती है और मैं तुरंत कहूंगा कि मैंने विभिन्न तरीकों का उपयोग करने की कोशिश की: मैंने उन सभी वर्गों को जोड़ा, जिन्हें क्वार्ट्ज ने सेवाओं में शामिल किया था और उनका उपयोग डीआई के माध्यम से किया था - लेकिन पूरी तरह से नहीं, जैसा कि बाद में पता चला), मैंने HostedService को जोड़ने की कोशिश की - यह या तो काम नहीं करता था (अंत में मैं क्वार्ट्ज के साथ काम करने के बारे में उपयोगी लेखों के लिए कुछ अच्छे लिंक संलग्न करता हूं) और इसी तरह। मैंने पहले से ही सोचा था कि मुझे ट्रिगर के साथ समस्या थी - न तो। इस छोटे से लेख में मैं उन लोगों की मदद करने की कोशिश करूंगा, जिनके पास एक ही समस्या हो सकती है और आशा है कि मेरा समाधान उनके भविष्य के काम में उनकी मदद करेगा। परिचय के अंत में, मैं यह जोड़ना चाहता हूं कि अगर मैं उन लोगों के प्रति आभारी रहूंगा, जो टिप्पणी से परिचित हैं, जो तकनीक से अच्छी तरह परिचित हैं, तो कुछ सलाह देते हैं जो मुझे प्रस्तावित करने में सुधार करने में मदद करेंगे।

क्वार्ट्ज


एक प्रोजेक्ट बनाएं (या एक समाप्त करें - यह कोई फर्क नहीं पड़ता) और दो फ़ोल्डर्स और कई वर्गों को इसमें जोड़ें:

क्वार्ट्ज
--DataJob.cs
--DataScheduler.cs
--JobFactory.cs
वर्कर्स -
EmailSender-
IEmailSender

IEmailSender इंटरफ़ेस में, जो एक उदाहरण के रूप में काम करेगा , पत्र भेजने के लिए एक विधि बनाएँ:

public interface IEmailSender
    {
        Task SendEmailAsync(string email, string subject, string message);
    }

अब हम उस वर्ग का वर्णन करते हैं जो इस इंटरफ़ेस को लागू करेगा:

public class EmailSender : IEmailSender
    {
        
        public Task SendEmailAsync(string email, string subject, string message)
		{
			var from = "****@gmail.com";
			var pass = "****";
            SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
			client.DeliveryMethod = SmtpDeliveryMethod.Network;
			client.UseDefaultCredentials = false;
			client.Credentials = new System.Net.NetworkCredential(from, pass);
			client.EnableSsl = true;
			var mail = new MailMessage(from, email);
			mail.Subject = subject;
			mail.Body = message;
			mail.IsBodyHtml = true;
			return client.SendMailAsync(mail);
		}
    }

अब हम कक्षाओं का वर्णन करते हैं DataJob.cs, DataScheduler.cs, JobFactory.cs। DataJob वर्ग IJob इंटरफ़ेस को लागू करेगा।

 public class DataJob : IJob
    {
        private readonly IServiceScopeFactory serviceScopeFactory;

        public DataJob(IServiceScopeFactory serviceScopeFactory)
        {
            this.serviceScopeFactory = serviceScopeFactory;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            using (var scope = serviceScopeFactory.CreateScope())
            {
                var emailsender = scope.ServiceProvider.GetService<IEmailSender>();
                
                 await emailsender.SendEmailAsync("example@gmail.com","example","hello")
            }
        }
    }

जैसा कि हम IS ISScopeFactory प्रकार का एक क्षेत्र देखते हैं, हम सीधे स्टार्टअप से सेवाएं प्राप्त करेंगे। यह वह दृष्टिकोण था जिसने मुझे अपनी समस्या को हल करने में मदद की, आगे बढ़ो और डेटास्क्लेडर वर्ग का वर्णन करें जिसमें हम नौकरी जोड़ेंगे और स्वयं क्वार्ट्ज के शेडयूलर में ट्रिगर करेंगे:

public static class DataScheduler
    {
        
        public static async void Start(IServiceProvider serviceProvider)
        {
            IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
            scheduler.JobFactory = serviceProvider.GetService<JobFactory>();
            await scheduler.Start();

            IJobDetail jobDetail = JobBuilder.Create<DataJob>().Build();
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("MailingTrigger", "default")
                .StartNow()
                .WithSimpleSchedule(x => x
                .WithIntervalInMinutes(1)
                .RepeatForever())
                .Build();

            await scheduler.ScheduleJob(jobDetail, trigger);
        }

और अब JobFactory वर्ग, जो IJobFactory इंटरफ़ेस को लागू करता है:

 public class JobFactory : IJobFactory
    {
        protected readonly IServiceScopeFactory serviceScopeFactory;

        
        public JobFactory(IServiceScopeFactory serviceScopeFactory)
        {
            this.serviceScopeFactory = serviceScopeFactory;
        }

        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            using (var scope = serviceScopeFactory.CreateScope())
            {
                var job = scope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob;
                return job;
            }
            
        }

        public void ReturnJob(IJob job)
        {
           //Do something if need
        }
    }

जैसा कि आप देख सकते हैं, मैं, वास्तव में, सभी निर्भरताएँ सीधे सेवा से प्राप्त कर सकता हूं। सब कुछ लगभग तैयार है, यह कार्यक्रम वर्ग को बदलने के लिए बना हुआ है:

public class Program
    {
        public static void Main(string[] args)
        {
            var host = BuildWebHost(args);
            using (var scope = host.Services.CreateScope())
            {
                var serviceProvider = scope.ServiceProvider;
                try
                {
                    DataScheduler.Start(serviceProvider);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            host.Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
           WebHost.CreateDefaultBuilder(args)
               .UseStartup<Startup>()
               .Build();
    }

और ConfigureServices विधि में निम्न को स्टार्टअप में जोड़ें:

   services.AddTransient<JobFactory>();
   services.AddScoped<DataJob>();
   services.AddScoped<IEmailSender,EmailSender>();

किया हुआ। अब जब आप आवेदन शुरू करते हैं, तो हम एक कार्य बनाते हैं जो हर मिनट में आग लगाएगा। मान को DataScheduler.Start में बदला जा सकता है (सेकंड में, घंटों में भी निर्दिष्ट किया जा सकता है या CRON का उपयोग किया जा सकता है)। इस दृष्टिकोण के साथ प्रत्येक नए कार्य के लिए, आपको एक नया वर्ग बनाने की आवश्यकता है जो IJob को लागू करेगा और एक नया DataScheduler कार्य पंजीकृत करेगा। आप एक नए कार्य के लिए एक अलग समयबद्धक वर्ग भी बना सकते हैं।

मुझे बहुत खुशी होगी अगर मैं किसी की मदद कर सकता हूं, लेकिन यहां क्वार्ट्ज और इसके उपयोग के बारे में उपयोगी लेखों के एक जोड़े हैं:

ASP.NET कोर के साथ एक Quartz.NET होस्ट की गई सेवा
का उपयोग करना।

Source: https://habr.com/ru/post/undefined/


All Articles