FruitBankHybridApp/FruitBankHybrid/MauiProgram.cs

102 lines
4.9 KiB
C#

using AyCode.Core.Loggers;
using AyCode.Services.SignalRs;
using FruitBank.Common.Loggers;
using FruitBank.Common.Models;
using FruitBank.Common.Services;
using FruitBankHybrid.Services;
using FruitBankHybrid.Services.Loggers;
using FruitBankHybrid.Shared.Databases;
using FruitBankHybrid.Shared.Services;
using FruitBankHybrid.Shared.Services.Loggers;
using FruitBankHybrid.Shared.Services.SignalRs;
//using DevExpress.Maui;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Reflection;
namespace FruitBankHybrid
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>()
//.UseDevExpress(useLocalization: false)
//.UseDevExpressCollectionView()
//.UseDevExpressControls()
//.UseDevExpressEditors()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
// Load embedded appsettings.json — MAUI has no automatic config file discovery,
// so the JSON is shipped as an EmbeddedResource (see FruitBankHybrid.csproj).
using (var appsettingsStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FruitBankHybrid.appsettings.json"))
{
if (appsettingsStream is not null)
{
var jsonConfig = new ConfigurationBuilder().AddJsonStream(appsettingsStream).Build();
builder.Configuration.AddConfiguration(jsonConfig);
}
}
#if DEBUG
builder.Services.AddSingleton<IAcLogWriterClientBase, BrowserConsoleLogWriter>();
#endif
builder.Services.AddSingleton<IAcLogWriterClientBase, SignaRClientLogItemWriter>();
// Logger options + framework factory. LoggerClient instances are created per caller category,
// with AppType+LogLevel from appsettings and writers resolved from DI via IAcLogWriterClientBase.
builder.Services.Configure<AcLoggerOptions>(builder.Configuration.GetSection("AyCode:Logger"));
builder.Services.AddAcLoggerFactory<LoggerClient, IAcLogWriterClientBase>();
// Bind SignalR options from configuration.
// Precedence: code default → appsettings.json (this line) → any later Configure<T> action.
builder.Services.Configure<AcHubConnectionOptions>(builder.Configuration.GetSection("AcHubConnection"));
builder.Services.Configure<AcBinaryHubProtocolOptions>(builder.Configuration.GetSection("AcBinaryHubProtocol"));
// Add device-specific services used by the FruitBankHybrid.Shared project
builder.Services.AddSingleton<IFormFactor, FormFactor>();
builder.Services.AddSingleton<ISecureCredentialService, MauiSecureCredentialService>();
builder.Services.AddSingleton<LoggedInModel>(sp => new LoggedInModel(sp.GetRequiredService<ISecureCredentialService>()));
// SignalR HubConnectionBuilder — transient so each consumer gets a fresh builder to Build().
// All connection and protocol configuration flows from appsettings.json via IOptions<T>;
// AddAcDefaults (framework) applies AcHubConnectionOptions and bridges the provided logger into SignalR's internal pipeline.
// NOTE: AcBinaryHubProtocolOptions is resolved from the OUTER service provider and passed
// explicitly — HubConnectionBuilder's inner DI cannot see outer services.Configure<T>() registrations.
builder.Services.AddTransient<IHubConnectionBuilder>(sp =>
{
var loggerFactory = sp.GetRequiredService<Func<string, LoggerClient>>();
var connectionOpts = sp.GetRequiredService<IOptions<AcHubConnectionOptions>>().Value;
var protocolOpts = sp.GetRequiredService<IOptions<AcBinaryHubProtocolOptions>>().Value;
var logger = loggerFactory(nameof(FruitBankSignalRClient));
var hubBuilder = new HubConnectionBuilder().AddAcDefaults(logger, connectionOpts);
hubBuilder.AddAcBinaryProtocol(protocolOpts);
return hubBuilder;
});
builder.Services.AddSingleton<FruitBankSignalRClient>();
builder.Services.AddSingleton<DatabaseClient>();
builder.Services.AddMauiBlazorWebView();
builder.Services.AddDevExpressBlazor(configure => configure.SizeMode = DevExpress.Blazor.SizeMode.Medium);
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
}