服务端的TigerApi 框架,基于.NET6 2024 版本
Ben Lin
2025-03-05 709959f7739b733b22b0be8557593b59f1b7ecd8
Tiger.Api/Program.cs
@@ -17,74 +17,103 @@
using Autofac;
using Tiger.IBusiness;
bool isService = Debugger.IsAttached ? false : Directory.GetCurrentDirectory().ToLower() == @"c:\windows\system32";
var pathToContentRoot = AppDomain.CurrentDomain.BaseDirectory;
if (isService)
var begin = DateTime.Now;
try
{
    var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
    pathToContentRoot = Path.GetDirectoryName(pathToExe) + "\\";
}
var options = new WebApplicationOptions
{
    Args = args,
    ContentRootPath = pathToContentRoot
};
   //非UI线程未捕获异常处理事件
   AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
   //Task 线程内未捕获异常处理事件
   TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
   bool isService = Debugger.IsAttached ? false : Directory.GetCurrentDirectory().ToLower() == @"c:\windows\system32";
   var pathToContentRoot = AppDomain.CurrentDomain.BaseDirectory;
   if (isService)
   {
       var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
       pathToContentRoot = Path.GetDirectoryName(pathToExe) + "\\";
   }
   var IsRunAsAdmin = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
   //var config = (new ConfigurationBuilder().SetBasePath(pathToContentRoot).AddJsonFile("appsettings.json")).Build();
   var prod = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute)).First() as AssemblyProductAttribute).Product;
   var vers = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute)).First() as AssemblyFileVersionAttribute).Version;
   var desc = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute)).First() as AssemblyDescriptionAttribute).Description;
   Logger.Default.Info($"{prod}(Version {vers}) {desc}");
   ConsoleExt.WriteLine("");
   ConsoleExt.WriteLine($"                         {prod}(Version {vers}) Base on .Net 6", ConsoleColor.Green);
   ConsoleExt.WriteLine("");
   ConsoleExt.Write($" ====== > ===== > ==== >---->--->-->-> >  ", ConsoleColor.DarkCyan);
   ConsoleExt.Write($"Link Start{(IsRunAsAdmin ? $" As Admin" : "")}", ConsoleColor.Cyan);
   ConsoleExt.WriteLine($"  < <-<--<---<----< ==== < ===== < ====== ", ConsoleColor.DarkCyan);
   Logger.Console.Info($"Begin to load {prod}");
var builder = WebApplication.CreateBuilder(options);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
    //AutoFac 配置文件注入
    AutoFacContainer.Init(builder);
    builder.RegisterBuildCallback(scope =>
    {
        AutoFacContainer.Instance = (IContainer)scope;
        //初始化Business的AutoFacContainer
        //DI.Resolve<IBiz>().SetContainer(AutoFacContainer.Instance = (IContainer)scope);
    System.Net.ServicePointManager.DefaultConnectionLimit = 1024;
    var options = new WebApplicationOptions
   {
       Args = args,
       ContentRootPath = pathToContentRoot,
   };
    var builder = WebApplication.CreateBuilder(options);
   builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
   builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
   {
       //AutoFac 配置文件注入
       AutoFacContainer.Init(builder);
       builder.RegisterBuildCallback(scope =>
       {
           AutoFacContainer.Instance = (IContainer)scope;
           //初始化Business的AutoFacContainer
           //DI.Resolve<IBiz>().SetContainer(AutoFacContainer.Instance = (IContainer)scope);
       });
       //builder.RegisterType<TestService>().As<ITest>();
   });
    Logger.Console.Info($"AutoFac container inject successful");
    var startup = new Startup(builder.Configuration);
   startup.ConfigureServices(builder.Services);
    var config = (new ConfigurationBuilder().SetBasePath(pathToContentRoot).AddJsonFile("appsettings.json")).Build();
   var urls = config.AsEnumerable().Where(q => q.Key.StartsWith("StartUpSetting:UseUrls") && q.Value != null).Select(q => q.Value).ToArray();
   builder.WebHost.UseUrls(urls);
   builder.WebHost.UseKestrel(opt =>
   {
        // 设置最大连接数
        opt.Limits.MaxConcurrentConnections = null;
        // 设置请求队列的长度
        opt.Limits.MaxConcurrentUpgradedConnections = null;
        opt.Limits.MinRequestBodyDataRate = null;
    });
    //builder.RegisterType<TestService>().As<ITest>();
});
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);
Main(args);
var config = (new ConfigurationBuilder().SetBasePath(pathToContentRoot).AddJsonFile("appsettings.json")).Build();
var urls = config.AsEnumerable().Where(q => q.Key.StartsWith("StartUpSetting:UseUrls") && q.Value != null).Select(q => q.Value).ToArray();
var prod = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute)).First() as AssemblyProductAttribute).Product;
builder.WebHost.UseUrls(urls);
builder.WebHost.UseKestrel(opt =>
{
    opt.Limits.MinRequestBodyDataRate = null;
});
    if (isService)
   {
      builder.Host.UseWindowsService();
       Logger.Default.Info("Run Api as Windows Services");
   }
    Logger.Console.Info($"Configure WebApplication successful");
    var app = builder.Build();
    Logger.Console.Info($"Build {prod} successful");
    // Fetch all the dependencies from the DI container 
    // var hostLifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
    // As pointed out by DavidFowler, IHostApplicationLifetime is exposed directly on ApplicationBuilder
    // Call Configure(), passing in the dependencies
    startup.Configure(app, app.Environment);
   Logger.Console.Info($"Run {prod} Successful");
    Logger.Console.Info($"Total Elapsed Time: {(DateTime.Now - begin).TotalSeconds:0.000} seconds");
if (isService)
{
   builder.Host.UseWindowsService();
    app.Run();
   Logger.Console.Info($"{prod} Host is shut down");
}
var app = builder.Build();
// Fetch all the dependencies from the DI container 
// var hostLifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
// As pointed out by DavidFowler, IHostApplicationLifetime is exposed directly on ApplicationBuilder
// Call Configure(), passing in the dependencies
startup.Configure(app, app.Environment);
Logger.Console.Info($"Run {prod} Host");
app.Run();
Logger.Console.Info($"{prod} Host is shut down");
void Main(string[] args)
catch (System.Exception ex)
{
    //非UI线程未捕获异常处理事件
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    //Task 线程内未捕获异常处理事件
    TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
    CreateWindowsServicesBuilder(args);
    Logger.Console.Fatal(ex, "Run {prod} Host Exception");
}
finally
{
    Logger.Console.Info($"Api Host finally shut down");
}
@@ -120,21 +149,22 @@
    Logger.Default.Fatal(e.Exception, $"捕获线程内未处理异常");
    e.SetObserved();//设置该异常已察觉(这样处理后就不会引起程序崩溃)
}
void CreateWindowsServicesBuilder(string[] args)
{
    try
    {
        //bool isService = Debugger.IsAttached ? false : Directory.GetCurrentDirectory().ToLower() == @"c:\windows\system32";
        bool isService = Debugger.IsAttached ? false : Directory.GetCurrentDirectory().ToLower() == @"c:\windows\system32";
        //var pathToContentRoot = AppDomain.CurrentDomain.BaseDirectory;
        //if (isService)
        //{
        //    var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
        //    pathToContentRoot = Path.GetDirectoryName(pathToExe) + "\\";
        //}
        var pathToContentRoot = AppDomain.CurrentDomain.BaseDirectory;
        if (isService)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            pathToContentRoot = Path.GetDirectoryName(pathToExe) + "\\";
        }
        var IsRunAsAdmin = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
        //var config = (new ConfigurationBuilder().SetBasePath(pathToContentRoot).AddJsonFile("appsettings.json")).Build();
        var config = (new ConfigurationBuilder().SetBasePath(pathToContentRoot).AddJsonFile("appsettings.json")).Build();
        var prod = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute)).First() as AssemblyProductAttribute).Product;
        var vers = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute)).First() as AssemblyFileVersionAttribute).Version;
        var desc = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute)).First() as AssemblyDescriptionAttribute).Description;
@@ -147,24 +177,24 @@
        ConsoleExt.WriteLine($"  < <-<--<---<----< ==== < ===== < ====== ", ConsoleColor.DarkCyan);
        Logger.Console.Info($"Run {prod} Host");
        //var urls = string.IsNullOrEmpty(config["StartUpSetting:UseUrls"]) ? "http://*:3810" : config["StartUpSetting:UseUrls"];
        //var urls = config.AsEnumerable().Where(q => q.Key.StartsWith("StartUpSetting:UseUrls") && q.Value != null).Select(q => q.Value).ToArray();
        //var host = WebHost.CreateDefaultBuilder(args)
        //    .UseContentRoot(pathToContentRoot)
        //    .UseUrls(urls)
        //    .UseStartup<Startup>()
        //    .Build();
        var urls = config.AsEnumerable().Where(q => q.Key.StartsWith("StartUpSetting:UseUrls") && q.Value != null).Select(q => q.Value).ToArray();
        var host = WebHost.CreateDefaultBuilder(args)
            .UseContentRoot(pathToContentRoot)
            .UseUrls(urls)
            .UseStartup<Startup>()
            .Build();
        //if (isService)
        //{
        //    host.RunAsApiService();
        //    //host.RunAsService();
        //}
        //else
        //{
        //    Logger.Console.Info($"Run {prod} Host");
        //    host.Run();
        //    Logger.Console.Info($"{prod} Host is shut down");
        //}
        if (isService)
        {
            host.RunAsApiService();
            //host.RunAsService();
        }
        else
        {
            Logger.Console.Info($"Run {prod} Host");
            host.Run();
            Logger.Console.Info($"{prod} Host is shut down");
        }
    }
    catch (System.Exception ex)
    {