服务端的TigerApi 框架,基于.NET6 2024 版本
YangYuGang
2 天以前 83d775ba1de1913e51fb216bc24d91305811f9bf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Rhea.Common;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System.Security.Principal;
using Microsoft.AspNetCore.Builder;
using Tiger.Api;
using Autofac.Extensions.DependencyInjection;
using Autofac;
using Tiger.IBusiness;
 
var begin = DateTime.Now;
try
{
    //非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}");
 
    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;
    });
 
    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");
 
    app.Run();
    Logger.Console.Info($"{prod} Host is shut down");
}
catch (System.Exception ex)
{
    Logger.Console.Fatal(ex, "Run {prod} Host Exception");
}
finally
{
    Logger.Console.Info($"Api Host finally shut down");
}
 
 
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    //StringBuilder sbEx = new StringBuilder();
    //if (e.IsTerminating)
    //{
    //    sbEx.Append("程序发生致命错误,将强制退出!\r\n");
    //}
    //sbEx.Append("非UI线程捕获未处理异常:");
    //if (e.ExceptionObject is Exception)
    //{
    //    sbEx.Append(((Exception)e.ExceptionObject).Message);
    //}
    //else
    //{
    //    sbEx.Append(e.ExceptionObject);
    //}
    //MessageBox.Show(sbEx.ToString());
    if (e.ExceptionObject is Exception)
    {
        Logger.Default.Fatal(e.ExceptionObject as Exception, $"非UI线程捕获未处理异常");
    }
    else
    {
        Logger.Default.Fatal($"非UI线程捕获未处理异常:{e.ExceptionObject}");
    }
}
void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    //Task 线程内未处理捕获
    Logger.Default.Fatal(e.Exception, $"捕获线程内未处理异常");
    e.SetObserved();//设置该异常已察觉(这样处理后就不会引起程序崩溃)
}
 
void CreateWindowsServicesBuilder(string[] args)
{
    try
    {
        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($"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();
 
        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)
    {
        Logger.Console.Fatal(ex, "Create Windows Services Failed");
    }
}