using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Telegrator.Core;
namespace Telegrator.Hosting.Web
{
///
/// Represents a web hosted telegram bot
///
public class TelegramBotWebHost : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable
{
private readonly WebApplication _innerApp;
private readonly IUpdateRouter _updateRouter;
private readonly ILogger _logger;
private bool _disposed;
///
public IServiceProvider Services => _innerApp.Services;
///
public IUpdateRouter UpdateRouter => _updateRouter;
///
public ICollection DataSources => ((IEndpointRouteBuilder)_innerApp).DataSources;
///
/// Allows consumers to be notified of application lifetime events.
///
public IHostApplicationLifetime Lifetime => _innerApp.Lifetime;
///
/// This application's logger
///
public ILogger Logger => _logger;
// Private interface fields
IServiceProvider IEndpointRouteBuilder.ServiceProvider => Services;
IServiceProvider IApplicationBuilder.ApplicationServices { get => Services; set => throw new NotImplementedException(); }
IFeatureCollection IApplicationBuilder.ServerFeatures => ((IApplicationBuilder)_innerApp).ServerFeatures;
IDictionary IApplicationBuilder.Properties => ((IApplicationBuilder)_innerApp).Properties;
///
/// Initializes a new instance of the class.
///
/// The proxied instance of host builder.
public TelegramBotWebHost(WebApplicationBuilder webApplicationBuilder)
{
// Building proxy application
_innerApp = webApplicationBuilder.Build();
_innerApp.UseTelegratorWeb();
// Reruesting services for this host
_updateRouter = Services.GetRequiredService();
_logger = Services.GetRequiredService>();
}
///
/// Creates new with default services and webhook update receiving scheme
///
///
public static TelegramBotWebHostBuilder CreateBuilder(WebApplicationOptions settings)
{
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
WebApplicationBuilder innerApp = WebApplication.CreateBuilder(settings);
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp, settings);
builder.Services.AddTelegramBotHostDefaults();
builder.Services.AddTelegramWebhook();
return builder;
}
///
/// Creates new SLIM with default services and webhook update receiving scheme
///
///
public static TelegramBotWebHostBuilder CreateSlimBuilder(WebApplicationOptions settings)
{
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
WebApplicationBuilder innerApp = WebApplication.CreateSlimBuilder(settings);
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp, settings);
builder.Services.AddTelegramBotHostDefaults();
builder.Services.AddTelegramWebhook();
return builder;
}
///
/// Creates new EMPTY WITHOUT any services or update receiving schemes
///
///
public static TelegramBotWebHostBuilder CreateEmptyBuilder(WebApplicationOptions settings)
{
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
WebApplicationBuilder innerApp = WebApplication.CreateEmptyBuilder(settings);
return new TelegramBotWebHostBuilder(innerApp, settings);
}
///
public async Task StartAsync(CancellationToken cancellationToken = default)
{
await _innerApp.StartAsync(cancellationToken);
}
///
public async Task StopAsync(CancellationToken cancellationToken = default)
{
await _innerApp.StopAsync(cancellationToken);
}
///
public IApplicationBuilder CreateApplicationBuilder()
=> ((IEndpointRouteBuilder)_innerApp).CreateApplicationBuilder();
///
public IApplicationBuilder Use(Func middleware)
=> _innerApp.Use(middleware);
///
public IApplicationBuilder New()
=> ((IApplicationBuilder)_innerApp).New();
///
public RequestDelegate Build()
=> ((IApplicationBuilder)_innerApp).Build();
///
/// Disposes the host.
///
public async ValueTask DisposeAsync()
{
if (_disposed)
return;
await _innerApp.DisposeAsync();
GC.SuppressFinalize(this);
_disposed = true;
}
///
/// Disposes the host.
///
public void Dispose()
{
if (_disposed)
return;
ValueTask disposeTask = _innerApp.DisposeAsync();
disposeTask.AsTask().Wait();
GC.SuppressFinalize(this);
_disposed = true;
}
}
}