diff --git a/Core/Core.cs b/Core/Core.cs index 9d342a9..d71056c 100644 --- a/Core/Core.cs +++ b/Core/Core.cs @@ -66,6 +66,7 @@ namespace Kruzya.TelegramBot.Core { _configuration = configuration; + HookAppDomain(); Start(); } @@ -156,5 +157,20 @@ namespace Kruzya.TelegramBot.Core return module; } + + private void HookAppDomain() + { + AppDomain.CurrentDomain.AssemblyResolve += delegate(object? sender, ResolveEventArgs args) + { + var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + string assemblyPath = Path.Combine(basePath, new AssemblyName(args.Name).Name + ".dll"); + if (!File.Exists(assemblyPath)) + { + return null; + } + + return Assembly.LoadFrom(assemblyPath); + }; + } } } diff --git a/Core/Core.csproj b/Core/Core.csproj index 2d8933e..21c37b2 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -8,6 +8,10 @@ + + + + diff --git a/Core/DbResolverParameter.cs b/Core/DbResolverParameter.cs new file mode 100644 index 0000000..58e8e51 --- /dev/null +++ b/Core/DbResolverParameter.cs @@ -0,0 +1,41 @@ +using System; +using BotFramework; +using Microsoft.EntityFrameworkCore; + +namespace Kruzya.TelegramBot.Core +{ + /// + /// Resolves the GUIDs from database to entities. + /// + /// Entity type + /// Database context where entity should be finded + public class DbResolverParameter : IParameterParser + where TAppContext : DbContext + where TResolvedEntity : class + { + private TAppContext _dbContext; + + public DbResolverParameter(TAppContext dbContext) + { + _dbContext = dbContext; + } + + public TResolvedEntity DefaultInstance() + { + return default(TResolvedEntity); + } + + public bool TryGetValue(string text, out TResolvedEntity result) + { + result = null; + Guid id; + if (Guid.TryParse(text, out id)) + { + result = _dbContext.Find(id); + return (result != null); + } + + return false; + } + } +} \ No newline at end of file diff --git a/Core/Extensions/RepositoryExtension.cs b/Core/Extensions/RepositoryExtension.cs new file mode 100644 index 0000000..98bafd4 --- /dev/null +++ b/Core/Extensions/RepositoryExtension.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; + +namespace Kruzya.TelegramBot.Core.Extensions +{ + public static class RepositoryExtension + { + #region DbContext + + /// + /// Marks the entity as created. + /// + /// + /// Entity for marking as created. + public static void MarkAsCreated(this DbContext dbContext, object entity) => + dbContext.Entry(entity).State = EntityState.Added; + + /// + /// Marks the entity as deleted. + /// + /// + /// Entity for marking as deleted. + public static void MarkAsDeleted(this DbContext dbContext, object entity) => + dbContext.Entry(entity).State = EntityState.Deleted; + + /// + /// Marks the entity as modified. + /// + /// + /// Entity for marking as modified. + public static void MarkAsModified(this DbContext dbContext, object entity) => + dbContext.Entry(entity).State = EntityState.Modified; + + #endregion + + #region Repository + + public static TEntity Create(this DbSet repository) where TEntity : class, new() + { + var entity = new TEntity(); + repository.Add(entity); + + return entity; + } + + #endregion + } +} \ No newline at end of file diff --git a/Core/Extensions/StartupExtension.cs b/Core/Extensions/StartupExtension.cs new file mode 100644 index 0000000..66c357a --- /dev/null +++ b/Core/Extensions/StartupExtension.cs @@ -0,0 +1,13 @@ +using System.Collections.Concurrent; +using Microsoft.Extensions.DependencyInjection; + +namespace Kruzya.TelegramBot.Core.Extensions +{ + public static class StartupExtension + { + public static IServiceCollection AddQueue(this IServiceCollection collection) + { + return collection.AddSingleton>(); + } + } +} \ No newline at end of file diff --git a/Core/Program.cs b/Core/Program.cs index f69b4b9..30931b0 100644 --- a/Core/Program.cs +++ b/Core/Program.cs @@ -12,6 +12,7 @@ namespace Kruzya.TelegramBot.Core public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .UseSystemd() .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); } } diff --git a/Core/Service/AbstractTimedHostedService.cs b/Core/Service/AbstractTimedHostedService.cs new file mode 100644 index 0000000..30a784c --- /dev/null +++ b/Core/Service/AbstractTimedHostedService.cs @@ -0,0 +1,76 @@ +using System; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using BotFramework; +using Microsoft.Extensions.Logging; +using Telegram.Bot.Exceptions; +using Telegram.Bot.Types; + +namespace Kruzya.TelegramBot.Core.Service +{ + public abstract class AbstractTimedHostedService + { + private Timer _timer; + + protected readonly ILogger _logger; + protected readonly ITelegramBot _bot; + + protected virtual TimeSpan TimerPeriod => TimeSpan.FromSeconds(45); + + protected AbstractTimedHostedService(ILogger logger, ITelegramBot bot) + { + _bot = bot; + _logger = logger; + } + + #region IHostedService + + public Task StartAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Message sender service is starting."); + _timer = new Timer(Run, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Message sender service is stopping."); + _timer?.Change(Timeout.Infinite, 0); + + return Task.CompletedTask; + } + + #endregion + #region IDisposable + /// + /// Disposes the timer. + /// + public void Dispose() + { + _timer?.Dispose(); + } + #endregion + + private async void Run(object state) + { + _timer?.Change(Timeout.Infinite, 0); + + try + { + await OnRun(); + } + finally + { + var timerPeriod = this.TimerPeriod; + _timer?.Change(timerPeriod, timerPeriod); + } + } + + protected virtual async Task OnRun() + { + await Task.Delay(500); + } + } +} \ No newline at end of file