Skip to content

Commit 24ada42

Browse files
committed
configuration pipelines, fluent builder host
1 parent 9001c11 commit 24ada42

13 files changed

+257
-99
lines changed

src/Http/Handlers/DefaultHttpServerHandler.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ namespace Sisk.Core.Http.Handlers;
1313

1414
internal class DefaultHttpServerHandler : HttpServerHandler
1515
{
16-
internal static Action<Router>? _routerSetup;
17-
internal static Action? _serverBootstraping;
16+
internal Action<Router>? _routerSetup;
17+
internal Action? _serverBootstraping;
1818

1919
protected override void OnServerStarting(HttpServer server)
2020
{

src/Http/Handlers/HttpServerHandlerRepository.cs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// Repository: https://github.com/sisk-http/core
99

1010
using Sisk.Core.Routing;
11+
using System.Reflection.Metadata;
1112
using System.Runtime.CompilerServices;
1213
using System.Runtime.InteropServices;
1314

@@ -17,10 +18,12 @@ internal class HttpServerHandlerRepository
1718
{
1819
private readonly HttpServer parent;
1920
private readonly List<HttpServerHandler> handlers = new List<HttpServerHandler>();
21+
internal readonly DefaultHttpServerHandler _default = new DefaultHttpServerHandler();
2022

2123
public HttpServerHandlerRepository(HttpServer parent)
2224
{
2325
this.parent = parent;
26+
this.RegisterHandler(_default);
2427
}
2528

2629
public void RegisterHandler(HttpServerHandler handler)

src/Http/Hosting/HttpServerHostContextBuilder.cs

+54-19
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ internal HttpServerHostContextBuilder()
4747
}
4848

4949
/// <summary>
50-
/// Gets or sets the Server Configuration object.
50+
/// Gets the Server Configuration object.
5151
/// </summary>
52-
public HttpServerConfiguration ServerConfiguration { get => _context.ServerConfiguration; set => value = _context.ServerConfiguration; }
52+
public HttpServerConfiguration ServerConfiguration { get => _context.ServerConfiguration; }
5353

5454
/// <summary>
5555
/// Builds an <see cref="HttpServerHostContext"/> with the specified parameters.
@@ -63,9 +63,10 @@ public HttpServerHostContext Build()
6363
/// Defines a function that will be executed immediately before starting the Http server.
6464
/// </summary>
6565
/// <param name="bootstrapAction">The action which will be executed before the Http server start.</param>
66-
public void UseBootstraper(Action bootstrapAction)
66+
public HttpServerHostContextBuilder UseBootstraper(Action bootstrapAction)
6767
{
68-
DefaultHttpServerHandler._serverBootstraping = bootstrapAction;
68+
_context.HttpServer.handler._default._serverBootstraping = bootstrapAction;
69+
return this;
6970
}
7071

7172
/// <summary>
@@ -77,7 +78,7 @@ public void UseBootstraper(Action bootstrapAction)
7778
/// call this method at the beginning of your builder, as the first immediate method.
7879
/// </remarks>
7980
/// <param name="portableConfigHandler">The handler of <see cref="PortableConfigurationBuilder"/>.</param>
80-
public void UsePortableConfiguration(Action<PortableConfigurationBuilder> portableConfigHandler)
81+
public HttpServerHostContextBuilder UsePortableConfiguration(Action<PortableConfigurationBuilder> portableConfigHandler)
8182
{
8283
_portableConfiguration = new PortableConfigurationBuilder(_context);
8384
try
@@ -107,90 +108,120 @@ public void UsePortableConfiguration(Action<PortableConfigurationBuilder> portab
107108
}
108109
Environment.Exit(2);
109110
}
111+
return this;
110112
}
111113

112114
/// <summary>
113115
/// Sets the main <see cref="ListeningPort"/> of this host builder.
114116
/// </summary>
115117
/// <param name="port">The port the server will listen on.</param>
116-
public void UseListeningPort(ushort port)
118+
public HttpServerHostContextBuilder UseListeningPort(ushort port)
117119
{
118120
_context.ServerConfiguration.ListeningHosts[0].Ports[0] = new ListeningPort(port);
121+
return this;
119122
}
120123

121124
/// <summary>
122125
/// Sets the main <see cref="ListeningPort"/> of this host builder.
123126
/// </summary>
124127
/// <param name="uri">The URI component that will be parsed to the listening port format.</param>
125-
public void UseListeningPort(string uri)
128+
public HttpServerHostContextBuilder UseListeningPort(string uri)
126129
{
127130
_context.ServerConfiguration.ListeningHosts[0].Ports[0] = new ListeningPort(uri);
131+
return this;
128132
}
129133

130134
/// <summary>
131135
/// Sets the main <see cref="ListeningPort"/> of this host builder.
132136
/// </summary>
133137
/// <param name="listeningPort">The <see cref="ListeningPort"/> object which the Http server will listen to.</param>
134-
public void UseListeningPort(ListeningPort listeningPort)
138+
public HttpServerHostContextBuilder UseListeningPort(ListeningPort listeningPort)
135139
{
136140
_context.ServerConfiguration.ListeningHosts[0].Ports[0] = listeningPort;
141+
return this;
137142
}
138143

139144
/// <summary>
140145
/// Overrides the <see cref="HttpServerConfiguration.DefaultCultureInfo"/> property in the HTTP server configuration.
141146
/// </summary>
142147
/// <param name="locale">The default <see cref="CultureInfo"/> object which the HTTP server will apply to the request handlers and callbacks thread.</param>
143-
public void UseLocale(CultureInfo locale)
148+
public HttpServerHostContextBuilder UseLocale(CultureInfo locale)
144149
{
145150
_context.ServerConfiguration.DefaultCultureInfo = locale;
151+
return this;
146152
}
147153

148154
/// <summary>
149155
/// Overrides the HTTP server flags with the provided flags.
150156
/// </summary>
151157
/// <param name="flags">The flags that will be set on the HTTP server.</param>
152-
public void UseFlags(HttpServerFlags flags)
158+
public HttpServerHostContextBuilder UseFlags(HttpServerFlags flags)
153159
{
154160
_context.ServerConfiguration.Flags = flags;
161+
return this;
155162
}
156163

157164
/// <summary>
158165
/// Calls an action that has the HTTP server configuration as an argument.
159166
/// </summary>
160167
/// <param name="handler">An action where the first argument is an <see cref="HttpServerConfiguration"/>.</param>
161-
public void UseConfiguration(Action<HttpServerConfiguration> handler)
168+
public HttpServerHostContextBuilder UseConfiguration(Action<HttpServerConfiguration> handler)
162169
{
163170
handler(_context.ServerConfiguration);
171+
return this;
164172
}
165173

166174
/// <summary>
167175
/// Calls an action that has the HTTP server instance as an argument.
168176
/// </summary>
169177
/// <param name="handler">An action where the first argument is the main <see cref="HttpServer"/> object.</param>
170-
public void UseHttpServer(Action<HttpServer> handler)
178+
public HttpServerHostContextBuilder UseHttpServer(Action<HttpServer> handler)
171179
{
172180
handler(_context.HttpServer);
181+
return this;
173182
}
174183

175184
/// <summary>
176185
/// Calls an action that has an <see cref="CrossOriginResourceSharingHeaders"/> instance from the main listening host as an argument.
177186
/// </summary>
178187
/// <param name="handler">An action where the first argument is the main <see cref="CrossOriginResourceSharingHeaders"/> object.</param>
179-
public void UseCors(Action<CrossOriginResourceSharingHeaders> handler)
188+
public HttpServerHostContextBuilder UseCors(Action<CrossOriginResourceSharingHeaders> handler)
180189
{
181190
if (_context.CrossOriginResourceSharingPolicy is null)
182191
_context.CrossOriginResourceSharingPolicy = CrossOriginResourceSharingHeaders.Empty;
183192

184193
handler(_context.CrossOriginResourceSharingPolicy);
194+
return this;
195+
}
196+
197+
/// <summary>
198+
/// Sets an <see cref="CrossOriginResourceSharingHeaders"/> instance in the current listening host.
199+
/// </summary>
200+
/// <param name="cors">The <see cref="CrossOriginResourceSharingHeaders"/> to the current host builder.</param>
201+
public HttpServerHostContextBuilder UseCors(CrossOriginResourceSharingHeaders cors)
202+
{
203+
_context.CrossOriginResourceSharingPolicy = cors;
204+
return this;
185205
}
186206

187207
/// <summary>
188208
/// Calls an action that has an <see cref="Router"/> instance from the host HTTP server.
189209
/// </summary>
190210
/// <param name="handler">An action where the first argument is the main <see cref="Router"/> object.</param>
191-
public void UseRouter(Action<Router> handler)
211+
public HttpServerHostContextBuilder UseRouter(Action<Router> handler)
212+
{
213+
_context.HttpServer.handler._default._routerSetup = handler;
214+
return this;
215+
}
216+
217+
/// <summary>
218+
/// Sets an <see cref="Router"/> instance in the current listening host.
219+
/// </summary>
220+
/// <param name="r">The <see cref="Router"/> to the current host builder.</param>
221+
public HttpServerHostContextBuilder UseRouter(Router r)
192222
{
193-
DefaultHttpServerHandler._routerSetup = handler;
223+
_context.Router = r;
224+
return this;
194225
}
195226

196227
/// <summary>
@@ -199,9 +230,10 @@ public void UseRouter(Action<Router> handler)
199230
/// <typeparam name="TModule">An class which implements <see cref="RouterModule"/>, or the router module itself.</typeparam>
200231
/// <param name="activateInstances">Optional. Determines whether found types should be defined as instances or static members.</param>
201232
[RequiresUnreferencedCode(SR.Router_AutoScanModules_RequiresUnreferencedCode)]
202-
public void UseAutoScan<TModule>(bool activateInstances = true) where TModule : RouterModule
233+
public HttpServerHostContextBuilder UseAutoScan<TModule>(bool activateInstances = true) where TModule : RouterModule
203234
{
204235
_context.Router.AutoScanModules<TModule>(typeof(TModule).Assembly, activateInstances);
236+
return this;
205237
}
206238

207239
/// <summary>
@@ -211,26 +243,29 @@ public void UseAutoScan<TModule>(bool activateInstances = true) where TModule :
211243
/// <param name="t">The assembly where the scanning types are.</param>
212244
/// <param name="activateInstances">Optional. Determines whether found types should be defined as instances or static members.</param>
213245
[RequiresUnreferencedCode(SR.Router_AutoScanModules_RequiresUnreferencedCode)]
214-
public void UseAutoScan<TModule>(Assembly t, bool activateInstances = true) where TModule : RouterModule
246+
public HttpServerHostContextBuilder UseAutoScan<TModule>(Assembly t, bool activateInstances = true) where TModule : RouterModule
215247
{
216248
_context.Router.AutoScanModules<TModule>(t, activateInstances);
249+
return this;
217250
}
218251

219252
/// <summary>
220253
/// This method is an shortcut for calling <see cref="HttpServer.RegisterHandler{T}"/>.
221254
/// </summary>
222255
/// <typeparam name="THandler">The handler which implements <see cref="HttpServerHandler"/>.</typeparam>
223-
public void UseHandler<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] THandler>() where THandler : HttpServerHandler, new()
256+
public HttpServerHostContextBuilder UseHandler<THandler>() where THandler : HttpServerHandler, new()
224257
{
225258
_context.HttpServer.RegisterHandler<THandler>();
259+
return this;
226260
}
227261

228262
/// <summary>
229263
/// This method is an shortcut for calling <see cref="HttpServer.RegisterHandler"/>.
230264
/// </summary>
231265
/// <param name="handler">The instance of the server handler.</param>
232-
public void UseHandler(HttpServerHandler handler)
266+
public HttpServerHostContextBuilder UseHandler(HttpServerHandler handler)
233267
{
234268
_context.HttpServer.RegisterHandler(handler);
269+
return this;
235270
}
236271
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// The Sisk Framework source code
2+
// Copyright (c) 2023 PROJECT PRINCIPIUM
3+
//
4+
// The code below is licensed under the MIT license as
5+
// of the date of its publication, available at
6+
//
7+
// File name: IConfigurationReadPipeline.cs
8+
// Repository: https://github.com/sisk-http/core
9+
10+
using Sisk.Core.Internal.ServiceProvider;
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using System.Text;
15+
using System.Threading.Tasks;
16+
17+
namespace Sisk.Core.Http.Hosting;
18+
19+
/// <summary>
20+
/// Represents an interface that reads and applies settings from a settings file.
21+
/// </summary>
22+
public interface IConfigurationReader
23+
{
24+
/// <summary>
25+
/// Represents the method that reads and applies settings from a settings file.
26+
/// </summary>
27+
/// <param name="context">The configuration context object.</param>
28+
public void ReadConfiguration(ConfigurationContext context);
29+
}

src/Http/Hosting/PortableConfigurationBuilder.cs

+43-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// Repository: https://github.com/sisk-http/core
99

1010
using Sisk.Core.Internal.ServiceProvider;
11+
using System.ComponentModel;
1112

1213
namespace Sisk.Core.Http.Hosting;
1314

@@ -19,7 +20,7 @@ public sealed class PortableConfigurationBuilder
1920
private readonly HttpServerHostContext _context;
2021
private string _filename = "service-config.json";
2122
bool _createIfDontExists = false;
22-
PortableConfigurationRequireSection _requiredSections = default;
23+
IConfigurationReader? _pipeline = null;
2324

2425
Action<InitializationParameterCollection>? _initializerHandler;
2526

@@ -30,45 +31,76 @@ internal PortableConfigurationBuilder(HttpServerHostContext context)
3031

3132
internal void Build()
3233
{
33-
ProviderContext provider = new ProviderContext(_filename)
34+
if (_createIfDontExists && !File.Exists(_filename))
3435
{
35-
Host = _context,
36-
TargetListeningHost = _context.ServerConfiguration.ListeningHosts[0],
37-
CreateConfigurationFileIfDoenstExists = _createIfDontExists
38-
};
36+
File.Create(_filename).Close();
37+
}
3938

40-
ConfigParser.ParseConfiguration(provider);
39+
ConfigurationContext provider = new ConfigurationContext(_filename, _context, _context.ServerConfiguration.ListeningHosts[0]);
40+
41+
var pipelineReader = _pipeline ?? new JsonConfigParser();
42+
pipelineReader.ReadConfiguration(provider);
4143

4244
if (_initializerHandler != null)
4345
_initializerHandler(_context.Parameters);
46+
47+
_context.Parameters.MakeReadonly();
48+
}
49+
50+
/// <summary>
51+
/// Defines an custom <see cref="IConfigurationReader"/> configuration pipeline to the builder.
52+
/// </summary>
53+
/// <param name="pipeline">The <see cref="IConfigurationReader"/> object.</param>
54+
public PortableConfigurationBuilder WithConfigurationPipeline(IConfigurationReader pipeline)
55+
{
56+
_pipeline = pipeline;
57+
return this;
58+
}
59+
60+
/// <summary>
61+
/// Defines an custom <see cref="IConfigurationReader"/> configuration pipeline to the builder.
62+
/// </summary>
63+
/// <typeparam name="TPipeline">The <see cref="IConfigurationReader"/> type.</typeparam>
64+
public PortableConfigurationBuilder WithConfigurationPipeline<TPipeline>() where TPipeline : IConfigurationReader, new()
65+
{
66+
_pipeline = new TPipeline();
67+
return this;
4468
}
4569

4670
/// <summary>
4771
/// Specifies the name of the server configuration file.
4872
/// </summary>
4973
/// <param name="filename">The name of the JSON configuration file.</param>
5074
/// <param name="createIfDontExists">Optional. Determines if the configuration file should be created if it doens't exists.</param>
51-
public void WithConfigFile(string filename, bool createIfDontExists = false)
75+
public PortableConfigurationBuilder WithConfigFile(string filename, bool createIfDontExists = false)
5276
{
53-
_filename = filename;
77+
_filename = Path.GetFullPath(filename);
5478
_createIfDontExists = createIfDontExists;
79+
return this;
5580
}
5681

5782
/// <summary>
5883
/// Invokes a method on the initialization parameter collection.
5984
/// </summary>
6085
/// <param name="handler">The handler of <see cref="InitializationParameterCollection"/>.</param>
61-
public void WithParameters(Action<InitializationParameterCollection> handler)
86+
public PortableConfigurationBuilder WithParameters(Action<InitializationParameterCollection> handler)
6287
{
6388
_initializerHandler = handler;
89+
return this;
6490
}
6591

6692
/// <summary>
6793
/// Specifies the required configuration sections in the configuration file.
6894
/// </summary>
6995
/// <param name="requiredSections">One or more required sections.</param>
96+
/// <remarks>
97+
/// This method is obsolete and won't be used anywhere in the code, and will be removed in later Sisk versions.
98+
/// </remarks>
99+
[Obsolete("This method is obsolete and won't be used anywhere in the code, and will be removed in later Sisk versions.")]
100+
[EditorBrowsable(EditorBrowsableState.Never)]
101+
[Browsable(false)]
70102
public void WithRequiredSections(PortableConfigurationRequireSection requiredSections)
71103
{
72-
_requiredSections = requiredSections;
104+
;
73105
}
74106
}

src/Http/Hosting/PortableConfigurationRequireSection.cs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace Sisk.Core.Http.Hosting;
1313
/// Defines which sessions are mandatory in the portable configuration file.
1414
/// </summary>
1515
[Flags]
16+
[Obsolete("This enum is not used anymore and will be removed in later Sisk versions.")]
1617
public enum PortableConfigurationRequireSection
1718
{
1819
/// <summary>

0 commit comments

Comments
 (0)