using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Ombi.Core.Notifications; using Ombi.Helpers; using Ombi.Notifications.Models; using Quartz; namespace Ombi.Notifications { public class NotificationService : INotificationService { private readonly IServiceProvider _provider; public NotificationService(IServiceProvider provider, ILogger log) { _provider = provider; Log = log; NotificationAgents = new List(); PopulateAgents(); } protected List NotificationAgents { get; } private ILogger Log { get; } /// /// Sends a notification to the user. This one is used in normal notification scenarios /// /// The model. /// public async Task Execute(IJobExecutionContext context) { JobDataMap dataMap = context.MergedJobDataMap; var model = (NotificationOptions)dataMap.Get(JobDataKeys.NotificationOptions); foreach (var agent in NotificationAgents) { await NotifyAsync(agent, model); } } private async Task NotifyAsync(INotification notification, NotificationOptions model) { try { await notification.NotifyAsync(model); } catch (Exception ex) { Log.LogError(LoggingEvents.Notification, ex, "Failed to notify for notification: {@notification}", notification); } } protected void PopulateAgents() { var baseSearchType = typeof(BaseNotification<>).Name; var ass = typeof(NotificationService).GetTypeInfo().Assembly; foreach (var ti in ass.DefinedTypes) { if (ti?.BaseType?.Name == baseSearchType) { var type = ti?.AsType(); var ctors = type.GetConstructors(); var ctor = ctors.FirstOrDefault(); var services = new List(); foreach (var param in ctor.GetParameters()) { services.Add(_provider.GetService(param.ParameterType)); } var item = Activator.CreateInstance(type, services.ToArray()); NotificationAgents.Add((INotification)item); } } } } }