-
Notifications
You must be signed in to change notification settings - Fork 0
/
Startup.cs
152 lines (121 loc) · 5.53 KB
/
Startup.cs
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
using AutoMapper;
using System;
using System.IO;
using System.Reflection;
using CodeStream.logDNA;
using CodeStresmAspNetCoreApiStarter.Data;
using CodeStresmAspNetCoreApiStarter.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using RedBear.LogDNA;
using SimpleInjector;
using SimpleInjector.Integration.AspNetCore.Mvc;
using SimpleInjector.Lifestyles;
using Swashbuckle.AspNetCore.Swagger;
namespace CodeStresmAspNetCoreApiStarter
{
public class Startup
{
private readonly Container container = new Container();
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
private AppSettings AppSettings => new AppSettings(Configuration);
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var thisAssembly = GetType().Assembly;
services.AddCors();
services.AddAutoMapper(thisAssembly);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
AddSimpleInjector(services);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "CodeStream API", Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
UseSimpleInjector(app);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors(builder => builder.WithOrigins(AppSettings.CorsAllowedOrigins)
.AllowAnyMethod()
.AllowAnyHeader());
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "CodeStream API V1");
});
// global exception handler
app.UseExceptionHandler(GlobalExceptionHandler.Handler(container.GetInstance<ILogDNALogger>()));
app.UseMvc();
}
private void AddSimpleInjector(IServiceCollection services)
{
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IControllerActivator>(new SimpleInjectorControllerActivator(container));
services.AddSingleton(Configuration);
//Ref: https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections
services.AddDbContext<EFContext>(opts =>
opts.UseSqlServer(AppSettings.PrimaryConnectionString,
sqlServerOptionsAction: optsAction =>
{
optsAction.EnableRetryOnFailure(maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(20), errorNumbersToAdd: null);
})
);
services.EnableSimpleInjectorCrossWiring(container);
services.UseSimpleInjectorAspNetRequestScoping(container);
}
private void UseSimpleInjector(IApplicationBuilder app)
{
container.RegisterMvcControllers(app);
container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies());
// Allow Simple Injector to resolve services from ASP.NET Core.
container.AutoCrossWireAspNetComponents(app);
RegisterLogDNAServicesInSimpleInjector(container);
container.Verify();
}
public void RegisterLogDNAServicesInSimpleInjector(Container container)
{
//TODO: extract this code into SimpleInjector IPackage class but then we need to solve global static access to AppSettings.
container.RegisterSingleton(() =>
{
var config = new ConfigurationManager(AppSettings.LogDNAInjestionKey)
{
HostName = AppSettings.LogDNAHostname,
FlushInterval = 500,
Tags = new[] { AppSettings.Environment, Assembly.GetExecutingAssembly().GetName().Version.ToString() }
};
var client = config.Initialise();
client.Connect();
return client;
});
container.RegisterSingleton(() => (ILogDNALogger)new LogDNALogger(container.GetInstance<IApiClient>(), AppSettings.LogDNAApp));
}
}
}