forked from Raiffeisen-DGTL/ViennaNET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCompanyHostBuilder.cs
More file actions
215 lines (177 loc) · 7.36 KB
/
Copy pathCompanyHostBuilder.cs
File metadata and controls
215 lines (177 loc) · 7.36 KB
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
204
205
206
207
208
209
210
211
212
213
214
215
using ViennaNET.Logging;
using ViennaNET.WebApi.Cors;
using ViennaNET.WebApi.Metrics;
using ViennaNET.WebApi.StaticFiles;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
namespace ViennaNET.WebApi
{
/// <summary>
/// Класс-строитель для создания и конфигурирования WebApi-сервисов
/// </summary>
public sealed partial class CompanyHostBuilder
{
private readonly Assembly _serviceAssembly;
private IHostEnvironment HostingEnvironment { get; set; }
private IConfiguration Configuration { get; set; }
private object _container;
private Func<object> _createContainerAction;
private Action<object> _verifyContainerAction;
private Action<IWebHostBuilder> _useServerAction;
private readonly List<Action<IMvcCoreBuilder, IConfiguration>> _mvcBuilderActions;
private Action<MvcOptions> _configureMvcOptions;
private readonly List<(Action<IApplicationBuilder, IConfiguration, IHostEnvironment, object> action, bool initBeforeContainer)>
_appActions;
private readonly List<Action<IApplicationBuilder>> _addMiddlewareActions;
private Func<IServiceCollection, IConfiguration, object> _configureContainerFunc;
private Action<IServiceCollection, IConfiguration, object> _configureContainerAction;
private Action<IApplicationBuilder, object, IConfiguration> _initializeContainerAction;
private readonly List<Action<IServiceCollection, IConfiguration>> _servicesToRegister;
private Action<IConfiguration> _onStartAction;
private Action<IConfiguration> _onStopAction;
private bool _useDefaultLogging = false;
private CompanyHostBuilder(Assembly serviceAssembly)
{
_serviceAssembly = serviceAssembly;
_appActions = new List<(Action<IApplicationBuilder, IConfiguration, IHostEnvironment, object> action, bool initBeforeContainer)>();
_addMiddlewareActions = new List<Action<IApplicationBuilder>>();
_servicesToRegister = new List<Action<IServiceCollection, IConfiguration>>();
_mvcBuilderActions = new List<Action<IMvcCoreBuilder, IConfiguration>>();
}
/// <summary>
/// Включает встроенный логгер
/// </summary>
/// <returns></returns>
public CompanyHostBuilder UseDefaultLogging()
{
_useDefaultLogging = true;
return this;
}
/// <summary>
/// Создает новый экземпляр строителя
/// </summary>
/// <returns></returns>
public static CompanyHostBuilder Create()
{
return new CompanyHostBuilder(Assembly.GetEntryAssembly());
}
private void ConfigureAppConfiguration(WebHostBuilderContext hostingContext, IConfigurationBuilder config)
{
HostingEnvironment = hostingContext.HostingEnvironment;
var serviceAssemblyName = _serviceAssembly.GetName();
var serviceAssemblyProps = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("serviceAssemblyName", serviceAssemblyName.Name),
new KeyValuePair<string, string>("serviceAssemblyVersion", serviceAssemblyName.Version?.ToString()),
};
config.AddInMemoryCollection(serviceAssemblyProps);
config.AddJsonFile(Path.GetDirectoryName(_serviceAssembly.Location) + "/conf/appsettings.json");
Configuration = config.Build();
}
private void ConfigureBaseServices(IServiceCollection services)
{
var builder = services.AddMvcCore(options =>
{
_configureMvcOptions?.Invoke(options);
options.EnableEndpointRouting = false;
})
.AddApiExplorer()
.AddApplicationPart(_serviceAssembly)
.AddCors();
_mvcBuilderActions.ForEach(a => a(builder, Configuration));
var name = _serviceAssembly.GetName();
Logger.DefaultService = name.Name;
_servicesToRegister.ForEach(service => service(services, Configuration));
}
private void ConfigureServices(IServiceCollection services)
{
ConfigureBaseServices(services);
_configureContainerAction?.Invoke(services, Configuration, _container);
}
// TODO: нужно доработать, сделать корректные интерфейсы
private object ConfigureServicesWithContainerReplace(IServiceCollection services)
{
ConfigureBaseServices(services);
return _configureContainerFunc(services, Configuration);
}
private void ConfigureAppBuilder(IApplicationBuilder app)
{
// Register configurations before initialize container
foreach (var configAction in _appActions.Where(a => a.initBeforeContainer))
{
configAction.action(app, Configuration, HostingEnvironment, _container);
}
_initializeContainerAction?.Invoke(app, _container, Configuration);
CorsConfigurator.Configure(app);
// Register middlewares
_addMiddlewareActions.ForEach(m => m(app));
// Register configurations after initialize container
foreach (var configAction in _appActions.Where(a => !a.initBeforeContainer))
{
configAction.action(app, Configuration, HostingEnvironment, _container);
}
// ASP.NET default stuff here
app.UseMvc();
app.ConfigureStaticFiles(Configuration);
_verifyContainerAction?.Invoke(_container);
// configure lifetime actions
if (_onStartAction is null && _onStopAction is null)
{
return;
}
var lifetime = app.ApplicationServices.GetService<IHostApplicationLifetime>();
if (_onStartAction != null)
{
lifetime.ApplicationStarted.Register(() => _onStartAction(Configuration));
}
if (_onStopAction != null)
{
lifetime.ApplicationStopped.Register(() => _onStopAction(Configuration));
}
}
/// <summary>
/// Собирает сервис
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public IWebHost BuildWebHost(string[] args)
{
VerifyBuilderState();
if (_createContainerAction != null)
{
_container = _createContainerAction();
}
var pathToExe = Process.GetCurrentProcess()
.MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
var hostBuilder = WebHost.CreateDefaultBuilder(args);
_useServerAction(hostBuilder);
hostBuilder.UseContentRoot(pathToContentRoot)
.ConfigureAppConfiguration(ConfigureAppConfiguration)
.ConfigureServices(ConfigureServices)
.ConfigureCompanyMetrics()
.Configure(ConfigureAppBuilder)
.ConfigureLogging(logBuilder =>
{
if (!_useDefaultLogging)
{
logBuilder.ClearProviders();
}
});
return hostBuilder.Build();
}
}
}