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
This commit is contained in:
FlorianDahn 2021-10-17 17:25:17 +02:00
parent 7004ee5963
commit a22ede0f4f
9 changed files with 271 additions and 82 deletions

View File

@ -20,8 +20,7 @@ namespace TelegramBotBase
/// Bot base class for full Device/Context and Messagehandling
/// </summary>
/// <typeparam name="T"></typeparam>
public class BotBase<T>
where T : FormBase
public class BotBase
{
public MessageClient Client { get; set; }
@ -33,7 +32,7 @@ namespace TelegramBotBase
/// <summary>
/// List of all running/active sessions
/// </summary>
public SessionBase<T> Sessions { get; set; }
public SessionBase Sessions { get; set; }
/// <summary>
/// Contains System commands which will be available at everytime and didnt get passed to forms, i.e. /start
@ -65,10 +64,15 @@ namespace TelegramBotBase
/// </summary>
public IStateMachine StateMachine { get; set; }
/// <summary>
/// Offers functionality to manage the creation process of the start form.
/// </summary>
public IStartFormFactory StartFormFactory { get; set; }
public Dictionary<eSettings, uint> SystemSettings { get; private set; }
private BotBase()
public BotBase()
{
this.SystemSettings = new Dictionary<eSettings, uint>();
@ -80,78 +84,10 @@ namespace TelegramBotBase
this.BotCommands = new List<BotCommand>();
this.Sessions = new SessionBase<T>();
this.Sessions = new SessionBase();
this.Sessions.BotBase = this;
}
/// <summary>
/// Simple start of your Bot with the APIKey
/// </summary>
/// <param name="apiKey"></param>
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;
}
/// <summary>
/// Simple start of your Bot with the APIKey and a proxyAdress
/// </summary>
/// <param name="apiKey"></param>
/// <param name="proxyBaseAddress">i.e. https://127.0.0.1:10000</param>
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;
}
/// <summary>
/// Simple start of your Bot with the APIKey and a TelegramBotClient instance.
/// </summary>
/// <param name="apiKey"></param>
/// <param name="client"></param>
public BotBase(String apiKey, TelegramBotClient client) : this(apiKey, false)
{
this.Client = new Base.MessageClient(this.APIKey, client);
this.Sessions.Client = this.Client;
}
/// <summary>
/// Simple start of your Bot with the APIKey and a proxyAdress
/// </summary>
/// <param name="apiKey"></param>
/// <param name="proxyBaseAddress">i.e. https://127.0.0.1:10000</param>
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;
}
/// <summary>
/// Simple start of your Bot with the APIKey and a proxyAdress
/// </summary>
/// <param name="apiKey"></param>
/// <param name="proxyHost">i.e. 127.0.0.1</param>
/// <param name="proxyPort">i.e. 10000</param>
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;
}
/// <summary>
/// Start your Bot
/// </summary>
@ -324,7 +260,7 @@ namespace TelegramBotBase
DeviceSession ds = e.Device;
if (ds == null)
{
ds = await this.Sessions.StartSession<T>(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<T>(e.DeviceId);
ds = await this.Sessions.StartSession(e.DeviceId);
e.Device = ds;
}

View File

@ -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<T>()
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;
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TelegramBotBase.Builder.Interfaces
{
public interface IAPIKeySelectionStage
{
/// <summary>
/// Sets the API Key which will be used by the telegram bot client.
/// </summary>
/// <param name="apiKey"></param>
/// <returns></returns>
IStartFormSelectionPage WithAPIKey(String apiKey);
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TelegramBotBase.Builder.Interfaces
{
public interface IBuildingStage
{
BotBase Build();
}
}

View File

@ -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
{
/// <summary>
/// Chooses a proxy as network configuration.
/// </summary>
/// <param name="proxyAddress"></param>
/// <returns></returns>
IBuildingStage WithProxy(String proxyAddress);
/// <summary>
/// Do not choose a proxy as network configuration.
/// </summary>
/// <returns></returns>
IBuildingStage NoProxy();
/// <summary>
/// Chooses a custom instance of TelegramBotClient.
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
IBuildingStage WithBotClient(TelegramBotClient client);
/// <summary>
/// Sets the custom proxy host and port.
/// </summary>
/// <param name="proxyHost"></param>
/// <param name="Port"></param>
/// <returns></returns>
IBuildingStage WithHostAndPort(String proxyHost, int Port);
/// <summary>
/// Uses a custom http client.
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
IBuildingStage WithHttpClient(HttpClient client);
}
}

View File

@ -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
{
/// <summary>
/// Chooses a start form type which will be used for new sessions.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
INetworkingSelectionStage WithStartForm(Type startFormClass);
/// <summary>
/// Chooses a generic start form which will be used for new sessions.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
INetworkingSelectionStage WithStartForm<T>() where T : FormBase, new();
/// <summary>
/// Chooses a StartFormFactory which will be use for new sessions.
/// </summary>
/// <param name="factory"></param>
/// <returns></returns>
INetworkingSelectionStage WithStartFormFactory(IStartFormFactory factory);
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using TelegramBotBase.Form;
namespace TelegramBotBase.Interfaces
{
public interface IStartFormFactory
{
FormBase CreateForm();
}
}

View File

@ -16,14 +16,13 @@ namespace TelegramBotBase
/// <summary>
/// Base class for managing all active sessions
/// </summary>
public class SessionBase<T>
where T : FormBase
public class SessionBase
{
public MessageClient Client { get; set; }
public Dictionary<long, DeviceSession> SessionList { get; set; }
public BotBase<T> BotBase { get; set; }
public BotBase BotBase { get; set; }
public SessionBase()
@ -65,10 +64,10 @@ namespace TelegramBotBase
/// <typeparam name="T"></typeparam>
/// <param name="deviceId"></param>
/// <returns></returns>
public async Task<DeviceSession> StartSession<T>(long deviceId)
where T : FormBase
public async Task<DeviceSession> 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
}
/// <summary>