From a22ede0f4fa982c041bfc62972931c53de45b91c Mon Sep 17 00:00:00 2001 From: FlorianDahn Date: Sun, 17 Oct 2021 17:25:17 +0200 Subject: [PATCH] Changing BotBase behaviour to fluent api - removing unecessary constructors from BotBase - removing generics from BotBase - removing generics from SessionBase - adding StartFormFactory interface - adding DefaultStartFormFactory - adding multiple methods to BotBaseBuilder --- TelegramBotBase/BotBase.cs | 86 ++------------ TelegramBotBase/Builder/BotBaseBuilder.cs | 105 ++++++++++++++++++ .../Interfaces/IAPIKeySelectionStage.cs | 17 +++ .../Builder/Interfaces/IBuildingStage.cs | 11 ++ .../Interfaces/INetworkingSelectionStage.cs | 49 ++++++++ .../Interfaces/IStartFormSelectionPage.cs | 34 ++++++ .../Factories/DefaultStartFormFactory.cs | 26 +++++ .../Interfaces/IStartFormFactory.cs | 12 ++ TelegramBotBase/SessionBase.cs | 13 +-- 9 files changed, 271 insertions(+), 82 deletions(-) create mode 100644 TelegramBotBase/Builder/BotBaseBuilder.cs create mode 100644 TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs create mode 100644 TelegramBotBase/Builder/Interfaces/IBuildingStage.cs create mode 100644 TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs create mode 100644 TelegramBotBase/Builder/Interfaces/IStartFormSelectionPage.cs create mode 100644 TelegramBotBase/Factories/DefaultStartFormFactory.cs create mode 100644 TelegramBotBase/Interfaces/IStartFormFactory.cs diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs index 9d9c354..9361281 100644 --- a/TelegramBotBase/BotBase.cs +++ b/TelegramBotBase/BotBase.cs @@ -20,8 +20,7 @@ namespace TelegramBotBase /// Bot base class for full Device/Context and Messagehandling /// /// - public class BotBase - where T : FormBase + public class BotBase { public MessageClient Client { get; set; } @@ -33,7 +32,7 @@ namespace TelegramBotBase /// /// List of all running/active sessions /// - public SessionBase Sessions { get; set; } + public SessionBase Sessions { get; set; } /// /// Contains System commands which will be available at everytime and didnt get passed to forms, i.e. /start @@ -65,10 +64,15 @@ namespace TelegramBotBase /// public IStateMachine StateMachine { get; set; } + /// + /// Offers functionality to manage the creation process of the start form. + /// + public IStartFormFactory StartFormFactory { get; set; } + public Dictionary SystemSettings { get; private set; } - private BotBase() + public BotBase() { this.SystemSettings = new Dictionary(); @@ -80,78 +84,10 @@ namespace TelegramBotBase this.BotCommands = new List(); - this.Sessions = new SessionBase(); + this.Sessions = new SessionBase(); this.Sessions.BotBase = this; } - /// - /// Simple start of your Bot with the APIKey - /// - /// - public BotBase(String apiKey, bool initClient = true) : this() - { - this.APIKey = apiKey; - - if (!initClient) - return; - - this.Client = new Base.MessageClient(this.APIKey); - this.Client.TelegramClient.Timeout = new TimeSpan(0, 1, 0); - - this.Sessions.Client = this.Client; - } - - /// - /// Simple start of your Bot with the APIKey and a proxyAdress - /// - /// - /// i.e. https://127.0.0.1:10000 - public BotBase(String apiKey, System.Net.Http.HttpClient proxy) : this(apiKey, false) - { - this.Client = new Base.MessageClient(this.APIKey, proxy); - - this.Sessions.Client = this.Client; - } - - /// - /// Simple start of your Bot with the APIKey and a TelegramBotClient instance. - /// - /// - /// - public BotBase(String apiKey, TelegramBotClient client) : this(apiKey, false) - { - this.Client = new Base.MessageClient(this.APIKey, client); - - this.Sessions.Client = this.Client; - } - - /// - /// Simple start of your Bot with the APIKey and a proxyAdress - /// - /// - /// i.e. https://127.0.0.1:10000 - public BotBase(String apiKey, String proxyBaseAddress) : this(apiKey, false) - { - var url = new Uri(proxyBaseAddress); - - this.Client = new Base.MessageClient(this.APIKey, url); - - this.Sessions.Client = this.Client; - } - - /// - /// Simple start of your Bot with the APIKey and a proxyAdress - /// - /// - /// i.e. 127.0.0.1 - /// i.e. 10000 - public BotBase(String apiKey, String proxyHost, int proxyPort) : this(apiKey, false) - { - this.Client = new Base.MessageClient(this.APIKey, proxyHost, proxyPort); - - this.Sessions.Client = this.Client; - } - /// /// Start your Bot /// @@ -324,7 +260,7 @@ namespace TelegramBotBase DeviceSession ds = e.Device; if (ds == null) { - ds = await this.Sessions.StartSession(e.DeviceId); + ds = await this.Sessions.StartSession(e.DeviceId); e.Device = ds; ds.LastMessage = e.Message; @@ -483,7 +419,7 @@ namespace TelegramBotBase DeviceSession ds = e.Device; if (ds == null) { - ds = await this.Sessions.StartSession(e.DeviceId); + ds = await this.Sessions.StartSession(e.DeviceId); e.Device = ds; } diff --git a/TelegramBotBase/Builder/BotBaseBuilder.cs b/TelegramBotBase/Builder/BotBaseBuilder.cs new file mode 100644 index 0000000..c4595f0 --- /dev/null +++ b/TelegramBotBase/Builder/BotBaseBuilder.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using Telegram.Bot; +using TelegramBotBase.Base; +using TelegramBotBase.Builder.Interfaces; +using TelegramBotBase.Form; +using TelegramBotBase.Interfaces; + +namespace TelegramBotBase.Builder +{ + public class BotBaseBuilder : IAPIKeySelectionStage, IStartFormSelectionPage, IBuildingStage, INetworkingSelectionStage + { + + String apiKey = null; + + IStartFormFactory factory = null; + + MessageClient client = null; + + public static IAPIKeySelectionStage Create() + { + return new BotBaseBuilder(); + } + + public IStartFormSelectionPage WithAPIKey(string apiKey) + { + this.apiKey = apiKey; + return this; + } + + public INetworkingSelectionStage WithStartForm(Type startFormClass) + { + this.factory = new Factories.DefaultStartFormFactory(startFormClass); + return this; + } + + public INetworkingSelectionStage WithStartForm() + where T : FormBase, new() + { + this.factory = new Factories.DefaultStartFormFactory(typeof(T)); + return this; + } + + public INetworkingSelectionStage WithStartFormFactory(IStartFormFactory factory) + { + this.factory = factory; + return this; + } + + + public IBuildingStage WithProxy(string proxyAddress) + { + var url = new Uri(proxyAddress); + client = new MessageClient(apiKey, url); + client.TelegramClient.Timeout = new TimeSpan(0, 1, 0); + return this; + } + + public IBuildingStage NoProxy() + { + client = new MessageClient(apiKey); + client.TelegramClient.Timeout = new TimeSpan(0, 1, 0); + return this; + } + + + public IBuildingStage WithBotClient(TelegramBotClient tgclient) + { + client = new MessageClient(apiKey, tgclient); + client.TelegramClient.Timeout = new TimeSpan(0, 1, 0); + return this; + } + + public IBuildingStage WithHostAndPort(string proxyHost, int proxyPort) + { + client = new MessageClient(apiKey, proxyHost, proxyPort); + client.TelegramClient.Timeout = new TimeSpan(0, 1, 0); + return this; + } + + public IBuildingStage WithHttpClient(HttpClient tgclient) + { + client = new MessageClient(apiKey, tgclient); + client.TelegramClient.Timeout = new TimeSpan(0, 1, 0); + return this; + } + + public BotBase Build() + { + var bb = new BotBase(); + + bb.APIKey = apiKey; + bb.StartFormFactory = factory; + + bb.Client = client; + + bb.Sessions.Client = bb.Client; + + return bb; + } + + } +} diff --git a/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs b/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs new file mode 100644 index 0000000..5e33a8f --- /dev/null +++ b/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TelegramBotBase.Builder.Interfaces +{ + public interface IAPIKeySelectionStage + { + /// + /// Sets the API Key which will be used by the telegram bot client. + /// + /// + /// + IStartFormSelectionPage WithAPIKey(String apiKey); + + } +} diff --git a/TelegramBotBase/Builder/Interfaces/IBuildingStage.cs b/TelegramBotBase/Builder/Interfaces/IBuildingStage.cs new file mode 100644 index 0000000..8313b0b --- /dev/null +++ b/TelegramBotBase/Builder/Interfaces/IBuildingStage.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TelegramBotBase.Builder.Interfaces +{ + public interface IBuildingStage + { + BotBase Build(); + } +} diff --git a/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs new file mode 100644 index 0000000..1a60a90 --- /dev/null +++ b/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using Telegram.Bot; + +namespace TelegramBotBase.Builder.Interfaces +{ + public interface INetworkingSelectionStage + { + /// + /// Chooses a proxy as network configuration. + /// + /// + /// + IBuildingStage WithProxy(String proxyAddress); + + /// + /// Do not choose a proxy as network configuration. + /// + /// + IBuildingStage NoProxy(); + + + /// + /// Chooses a custom instance of TelegramBotClient. + /// + /// + /// + IBuildingStage WithBotClient(TelegramBotClient client); + + /// + /// Sets the custom proxy host and port. + /// + /// + /// + /// + IBuildingStage WithHostAndPort(String proxyHost, int Port); + + /// + /// Uses a custom http client. + /// + /// + /// + IBuildingStage WithHttpClient(HttpClient client); + + + } +} diff --git a/TelegramBotBase/Builder/Interfaces/IStartFormSelectionPage.cs b/TelegramBotBase/Builder/Interfaces/IStartFormSelectionPage.cs new file mode 100644 index 0000000..05ba793 --- /dev/null +++ b/TelegramBotBase/Builder/Interfaces/IStartFormSelectionPage.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TelegramBotBase.Form; +using TelegramBotBase.Interfaces; + +namespace TelegramBotBase.Builder.Interfaces +{ + public interface IStartFormSelectionPage + { + + /// + /// Chooses a start form type which will be used for new sessions. + /// + /// + /// + INetworkingSelectionStage WithStartForm(Type startFormClass); + + /// + /// Chooses a generic start form which will be used for new sessions. + /// + /// + /// + INetworkingSelectionStage WithStartForm() where T : FormBase, new(); + + /// + /// Chooses a StartFormFactory which will be use for new sessions. + /// + /// + /// + INetworkingSelectionStage WithStartFormFactory(IStartFormFactory factory); + + } +} diff --git a/TelegramBotBase/Factories/DefaultStartFormFactory.cs b/TelegramBotBase/Factories/DefaultStartFormFactory.cs new file mode 100644 index 0000000..e3c7c20 --- /dev/null +++ b/TelegramBotBase/Factories/DefaultStartFormFactory.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TelegramBotBase.Form; + +namespace TelegramBotBase.Factories +{ + public class DefaultStartFormFactory : Interfaces.IStartFormFactory + { + private readonly Type _startFormClass; + + public DefaultStartFormFactory(Type startFormClass) + { + if (!typeof(FormBase).IsAssignableFrom(startFormClass)) + throw new ArgumentException("startFormClass argument must be a FormBase type"); + + _startFormClass = startFormClass; + } + + + public FormBase CreateForm() + { + return _startFormClass.GetConstructor(new Type[] { })?.Invoke(new object[] { }) as FormBase; + } + } +} diff --git a/TelegramBotBase/Interfaces/IStartFormFactory.cs b/TelegramBotBase/Interfaces/IStartFormFactory.cs new file mode 100644 index 0000000..7c1c44d --- /dev/null +++ b/TelegramBotBase/Interfaces/IStartFormFactory.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TelegramBotBase.Form; + +namespace TelegramBotBase.Interfaces +{ + public interface IStartFormFactory + { + FormBase CreateForm(); + } +} diff --git a/TelegramBotBase/SessionBase.cs b/TelegramBotBase/SessionBase.cs index 33dc0fb..60e947f 100644 --- a/TelegramBotBase/SessionBase.cs +++ b/TelegramBotBase/SessionBase.cs @@ -16,14 +16,13 @@ namespace TelegramBotBase /// /// Base class for managing all active sessions /// - public class SessionBase - where T : FormBase + public class SessionBase { public MessageClient Client { get; set; } public Dictionary SessionList { get; set; } - public BotBase BotBase { get; set; } + public BotBase BotBase { get; set; } public SessionBase() @@ -65,10 +64,10 @@ namespace TelegramBotBase /// /// /// - public async Task StartSession(long deviceId) - where T : FormBase + public async Task StartSession(long deviceId) { - T start = typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { }) as T; + var start = BotBase.StartFormFactory.CreateForm(); + //T start = typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { }) as T; start.Client = this.Client; @@ -239,7 +238,7 @@ namespace TelegramBotBase } - + ///