using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Features.AttributeFilters;
using AutoMapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Q1.Activity.Cache;
using Q1.Activity.MgmtApi.Ioc;
using Q1.Activity.MgmtApi.Middleware;
using Q1.Activity.MgmtApi.Models;
using Q1.Activity.MgmtApi.Models.Settings;
using Q1.Foundation.ApiClient;
using Q1.Foundation.LdapConnector;
using Q1.Foundation.RabbitConnector;
using Q1.Foundation.RepoLibs;
using Q1.Foundation.RepoLibs.Models;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using Serilog;
using Swashbuckle.AspNetCore.Swagger;
using System;
using System.IO;
using System.Reflection;
using System.Text;
namespace Q1.Activity.MgmtApi
{
public class Startup
{
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = configuration;
HostingEnvironment = env;
}
public IConfiguration Configuration { get; }
public IHostingEnvironment HostingEnvironment { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddControllersAsServices();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.CreateLogger();
services.AddLogging(config => {
config.AddConsole();
config.AddEventSourceLogger();
config.AddSerilog();
});
//Swagger
Assembly assemblyApi = Assembly.GetExecutingAssembly();
Assembly assemblyModels = Assembly.GetAssembly(typeof(Q1.Activity.Models.DataEntity.Activity));
string binPath = Path.GetDirectoryName(assemblyApi.Location);
services.AddSwaggerGen(option =>
{
option.SwaggerDoc("activitymgmt", new Info() { Title = "Activity Management Api", Version = "v1", Description = "活动管理接口" });
option.IncludeXmlComments(Path.Combine(binPath, $"{assemblyApi.GetName().Name}.xml"));
option.IncludeXmlComments(Path.Combine(binPath, $"{assemblyModels.GetName().Name}.xml"));
option.CustomSchemaIds(x => x.FullName);
});
//Register ConnectionStrings section
services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
//Register LdapConnector
services.Configure<LdapConfig>(Configuration.GetSection("Ldap"));
services.AddLdap();
services.Configure<UserContext>(Configuration.GetSection("UserContext"));
//Register MongoLib, it's depends on ConnectionStrings
services.AddSingleton<IMongoLib, MongoLib>();
services.AddSingleton<IRedisLib, RedisLib>();
services.AddRabbitConnection(Configuration);
services.AddSingleton<SocketAdapter>();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
//AutoMapper
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new AutoMapperProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
//Quartz Job
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
services.AddSingleton<OperationSessionJob>();
services.AddSingleton<GameCacheRefreshJob>();
services.AddSingleton<IJobFactory, JobFactory>();
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType<RedisLib>()
.UsingConstructor(typeof(string))
.WithParameter("connectionString", Configuration.GetSection("ConnectionStrings:RedisCache").Value)
.Named<IRedisLib>("RedisCache")
.SingleInstance();
builder.RegisterType<OperationSessionCache>().AsSelf().WithAttributeFiltering();
builder.RegisterType<RedisCache>().As<ICache>().WithAttributeFiltering();
var container = builder.Build();
IServiceProvider serviceProvider = container.Resolve<IServiceProvider>();
//Check database and try to initialize
var dataPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "InitialData");
serviceProvider.GetService<IMongoLib>().InitializeData(HostingEnvironment.EnvironmentName, dataPath);
//Listen Game response
serviceProvider.GetService<SocketAdapter>().ListenGameResponse();
//Schedule and start OperationSession job
var schedulerFactory = serviceProvider.GetService<ISchedulerFactory>();
var scheduler = schedulerFactory.GetScheduler().Result;
scheduler.Start().Wait();
scheduler.JobFactory = serviceProvider.GetService<IJobFactory>();
var jobOpsCache = JobBuilder.Create<OperationSessionJob>().WithIdentity("OperationCachePersist").Build();
var jobGameCache = JobBuilder.Create<GameCacheRefreshJob>().WithIdentity("GameCacheRefresh").Build();
var refreshInterval = serviceProvider.GetService<IOptions<AppSettings>>().Value.CacheRefreshInterval;
var triggerOpsCache = TriggerBuilder.Create().WithSimpleSchedule(s => s.WithIntervalInMinutes(10).RepeatForever()).Build();
var triggerGameCache = TriggerBuilder.Create().WithSimpleSchedule(s => s.WithIntervalInMinutes(refreshInterval).RepeatForever()).Build();
scheduler.ScheduleJob(jobOpsCache, triggerOpsCache).Wait();
scheduler.ScheduleJob(jobGameCache, triggerGameCache).Wait();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
return serviceProvider;
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMiddleware<ErrorHandling>();
app.UseStaticFiles();
app.UseWebSockets(new WebSocketOptions
{
KeepAliveInterval = new TimeSpan(1, 0, 0)
});
app.UseMvc();
// 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/activitymgmt/swagger.json", "Activity Management Api");
});
}
}
}