From b2d4c4c3f8e44c77e56373ca3fb40a37a93cba1b Mon Sep 17 00:00:00 2001 From: ZavaruKitsu Date: Fri, 19 Aug 2022 15:54:36 +0300 Subject: [PATCH] feat: add DI form factory --- Examples/EFCoreBot/Database/BotDbContext.cs | 12 +++++++ Examples/EFCoreBot/Database/User.cs | 7 ++++ Examples/EFCoreBot/EFCoreBot.csproj | 19 ++++++++++ Examples/EFCoreBot/Program.cs | 23 ++++++++++++ Examples/EFCoreBot/StartForm.cs | 36 +++++++++++++++++++ TelegramBotBase/Builder/BotBaseBuilder.cs | 16 ++++++++- .../Interfaces/IStartFormSelectionStage.cs | 16 +++++++++ .../ServiceProviderStartFormFactory.cs | 35 ++++++++++++++++++ TelegramBotBase/TelegramBotBase.csproj | 1 + TelegramBotFramework.sln | 7 ++++ 10 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 Examples/EFCoreBot/Database/BotDbContext.cs create mode 100644 Examples/EFCoreBot/Database/User.cs create mode 100644 Examples/EFCoreBot/EFCoreBot.csproj create mode 100644 Examples/EFCoreBot/Program.cs create mode 100644 Examples/EFCoreBot/StartForm.cs create mode 100644 TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs diff --git a/Examples/EFCoreBot/Database/BotDbContext.cs b/Examples/EFCoreBot/Database/BotDbContext.cs new file mode 100644 index 0000000..18a3c4a --- /dev/null +++ b/Examples/EFCoreBot/Database/BotDbContext.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; + +namespace EFCoreBot.Database; + +public class BotDbContext : DbContext +{ + public BotDbContext(DbContextOptions options) : base(options) + { + } + + public DbSet Users { get; set; } +} diff --git a/Examples/EFCoreBot/Database/User.cs b/Examples/EFCoreBot/Database/User.cs new file mode 100644 index 0000000..e106815 --- /dev/null +++ b/Examples/EFCoreBot/Database/User.cs @@ -0,0 +1,7 @@ +namespace EFCoreBot.Database; + +public class User +{ + public long Id { get; set; } + public string LastMessage { get; set; } +} diff --git a/Examples/EFCoreBot/EFCoreBot.csproj b/Examples/EFCoreBot/EFCoreBot.csproj new file mode 100644 index 0000000..324c2a9 --- /dev/null +++ b/Examples/EFCoreBot/EFCoreBot.csproj @@ -0,0 +1,19 @@ + + + + Exe + net6.0 + enable + disable + + + + + + + + + + + + diff --git a/Examples/EFCoreBot/Program.cs b/Examples/EFCoreBot/Program.cs new file mode 100644 index 0000000..fa427ee --- /dev/null +++ b/Examples/EFCoreBot/Program.cs @@ -0,0 +1,23 @@ +using EFCoreBot; +using EFCoreBot.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using TelegramBotBase.Builder; + +var serviceCollection = new ServiceCollection() + .AddDbContext(x => x.UseInMemoryDatabase("TelegramBotBase")); + +var serviceProvider = serviceCollection.BuildServiceProvider(); + +var bot = BotBaseBuilder.Create() + .WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set")) + .DefaultMessageLoop() + .WithServiceProvider(serviceProvider) + .NoProxy() + .NoCommands() + .NoSerialization() + .DefaultLanguage() + .Build(); + +bot.Start(); +await Task.Delay(-1); diff --git a/Examples/EFCoreBot/StartForm.cs b/Examples/EFCoreBot/StartForm.cs new file mode 100644 index 0000000..1bfee77 --- /dev/null +++ b/Examples/EFCoreBot/StartForm.cs @@ -0,0 +1,36 @@ +using EFCoreBot.Database; +using TelegramBotBase.Base; +using TelegramBotBase.Form; + +namespace EFCoreBot; + +public class StartForm : FormBase +{ + private readonly BotDbContext _dbContext; + + public StartForm(BotDbContext dbContext) + { + _dbContext = dbContext; + } + + public override async Task Load(MessageResult message) + { + var user = await _dbContext.Users.FindAsync(Device.DeviceId); + if (user is null) + { + user = new User + { + Id = Device.DeviceId, + LastMessage = "" + }; + + _dbContext.Users.Add(user); + await _dbContext.SaveChangesAsync(); + } + + await Device.Send($"Your last message's text was: `{user.LastMessage}`"); + + user.LastMessage = string.IsNullOrWhiteSpace(message.MessageText) ? "" : message.MessageText; + await _dbContext.SaveChangesAsync(); + } +} diff --git a/TelegramBotBase/Builder/BotBaseBuilder.cs b/TelegramBotBase/Builder/BotBaseBuilder.cs index d99aa9c..6ad24ee 100644 --- a/TelegramBotBase/Builder/BotBaseBuilder.cs +++ b/TelegramBotBase/Builder/BotBaseBuilder.cs @@ -7,6 +7,7 @@ using Telegram.Bot.Types; using TelegramBotBase.Base; using TelegramBotBase.Builder.Interfaces; using TelegramBotBase.Commands; +using TelegramBotBase.Factories; using TelegramBotBase.Form; using TelegramBotBase.Interfaces; using TelegramBotBase.Localizations; @@ -148,7 +149,7 @@ namespace TelegramBotBase.Builder #endregion - #region "Step 3 (Start Form/Factory)" + #region "Step 3 (Start Form/Factory)" public INetworkingSelectionStage WithStartForm(Type startFormClass) { @@ -163,6 +164,19 @@ namespace TelegramBotBase.Builder return this; } + public INetworkingSelectionStage WithServiceProvider(Type startFormClass, IServiceProvider serviceProvider) + { + this._factory = new ServiceProviderStartFormFactory(startFormClass, serviceProvider); + return this; + } + + public INetworkingSelectionStage WithServiceProvider(IServiceProvider serviceProvider) + where T : FormBase + { + this._factory = new ServiceProviderStartFormFactory(serviceProvider); + return this; + } + public INetworkingSelectionStage WithStartFormFactory(IStartFormFactory factory) { this._factory = factory; diff --git a/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs index fec05b3..78692ea 100644 --- a/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs +++ b/TelegramBotBase/Builder/Interfaces/IStartFormSelectionStage.cs @@ -23,6 +23,22 @@ namespace TelegramBotBase.Builder.Interfaces /// INetworkingSelectionStage WithStartForm() where T : FormBase, new(); + /// + /// Chooses a StartFormFactory which will be use for new sessions. + /// + /// + /// + /// + INetworkingSelectionStage WithServiceProvider(Type startFormClass, IServiceProvider serviceProvider); + + /// + /// Chooses a StartFormFactory which will be use for new sessions. + /// + /// + /// + /// + INetworkingSelectionStage WithServiceProvider(IServiceProvider serviceProvider) where T : FormBase; + /// /// Chooses a StartFormFactory which will be use for new sessions. /// diff --git a/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs b/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs new file mode 100644 index 0000000..4f2a0ef --- /dev/null +++ b/TelegramBotBase/Factories/ServiceProviderStartFormFactory.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using TelegramBotBase.Form; +using TelegramBotBase.Interfaces; + +namespace TelegramBotBase.Factories +{ + public class ServiceProviderStartFormFactory : IStartFormFactory + { + private readonly Type _startFormClass; + private readonly IServiceProvider _serviceProvider; + + public ServiceProviderStartFormFactory(Type startFormClass, IServiceProvider serviceProvider) + { + if (!typeof(FormBase).IsAssignableFrom(startFormClass)) + throw new ArgumentException("startFormClass argument must be a FormBase type"); + + _startFormClass = startFormClass; + _serviceProvider = serviceProvider; + } + + public FormBase CreateForm() + { + return (FormBase)ActivatorUtilities.CreateInstance(_serviceProvider, _startFormClass); + } + } + + public class ServiceProviderStartFormFactory : ServiceProviderStartFormFactory + where T : FormBase + { + public ServiceProviderStartFormFactory(IServiceProvider serviceProvider) : base(typeof(T), serviceProvider) + { + } + } +} diff --git a/TelegramBotBase/TelegramBotBase.csproj b/TelegramBotBase/TelegramBotBase.csproj index 7c24fbe..05c9802 100644 --- a/TelegramBotBase/TelegramBotBase.csproj +++ b/TelegramBotBase/TelegramBotBase.csproj @@ -23,6 +23,7 @@ + diff --git a/TelegramBotFramework.sln b/TelegramBotFramework.sln index 1c3ceeb..34eec3f 100644 --- a/TelegramBotFramework.sln +++ b/TelegramBotFramework.sln @@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase.Extensions.Serializer.Database.MSSQL", "TelegramBotBase.Extensions.Serializer.Database.MSSQL\TelegramBotBase.Extensions.Serializer.Database.MSSQL.csproj", "{889B170E-32E9-4F26-BB04-8D06EA367857}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCoreBot", "Examples\EFCoreBot\EFCoreBot.csproj", "{261BED47-0404-4A9A-86FC-047DE42A7D25}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -60,6 +62,10 @@ Global {889B170E-32E9-4F26-BB04-8D06EA367857}.Debug|Any CPU.Build.0 = Debug|Any CPU {889B170E-32E9-4F26-BB04-8D06EA367857}.Release|Any CPU.ActiveCfg = Release|Any CPU {889B170E-32E9-4F26-BB04-8D06EA367857}.Release|Any CPU.Build.0 = Release|Any CPU + {261BED47-0404-4A9A-86FC-047DE42A7D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {261BED47-0404-4A9A-86FC-047DE42A7D25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {261BED47-0404-4A9A-86FC-047DE42A7D25}.Release|Any CPU.ActiveCfg = Release|Any CPU + {261BED47-0404-4A9A-86FC-047DE42A7D25}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -70,6 +76,7 @@ Global {B5DDFA45-0E01-46A5-B67D-541300CDD606} = {E3193182-6FDA-4FA3-AD26-A487291E7681} {673A56F5-6110-4AED-A68D-562FD6ED3EA6} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} {889B170E-32E9-4F26-BB04-8D06EA367857} = {E3193182-6FDA-4FA3-AD26-A487291E7681} + {261BED47-0404-4A9A-86FC-047DE42A7D25} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {59CB40E1-9FA7-4867-A56F-4F418286F057}