[.net core template project] WebApi with Autofac
· 5 min read
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>bin\Debug\netcoreapp2.2\Q1.Activity.MgmtApi.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>bin\Release\netcoreapp2.2\Q1.Activity.MgmtApi.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetCore.NPOI" Version="1.2.2" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Q1.Foundation.ApiClient" Version="1.0.1" />
<PackageReference Include="Q1.Foundation.RepoLibs" Version="0.1.0" />
<PackageReference Include="Q1.Foundation.LdapConnector" Version="1.0.4" />
<PackageReference Include="Q1.Foundation.RabbitConnector" Version="1.0.1" />
<PackageReference Include="Q1.Foundation.Utils" Version="1.0.1" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.4" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="7.1.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Q1.Activity.Cache\Q1.Activity.Cache.csproj" />
<ProjectReference Include="..\Q1.Activity.Models\Q1.Activity.Models.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.Testing.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="InitialData\InitialData.Q1User.Integration.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="InitialData\InitialData.Q1User.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="InitialData\InitialData.SystemSettings..json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
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");
});
}
}
}
using Autofac.Features.AttributeFilters;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Q1.Foundation.RepoLibs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DataEntity = Q1.Activity.Models.DataEntity;
using Interface = Q1.Activity.Models.Interface;
using Internal = Q1.Activity.Models.Internal;
namespace Q1.Activity.Cache
{
public class RedisCache : ICache
{
readonly IMongoLib _db;
readonly IRedisLib _redis;
readonly IHostingEnvironment _env;
public RedisCache(IMongoLib db, [KeyFilter("RedisCache")]IRedisLib redis, IHostingEnvironment env)
{
_db = db;
_redis = redis;
_env = env;
}
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"System": "Warning",
"Microsoft": "Warning"
}
},
"Serilog": {
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Elasticsearch",
"Args": {
"nodeUris": "http://172.16.126.22:9200",
"indexFormat": "activitymgmt-api-{0:yyyy.MM.dd}",
"autoRegisterTemplate": true
}
}
]
},
"AllowedHosts": "*",
"rabbit": {
"uri": "amqp://guest:[email protected]:5672"
},
"ConnectionStrings": {
"Mongo": "mongodb://activity:Bing%[email protected]:27017,172.16.127.99:27017,172.16.127.120:27017/ActivityManagement",
"Redis": "172.16.127.229:6379", // Remote Socket Server Registy
"RedisCache": "172.16.127.229:6379,defaultDatabase=1" // Local Cache
},
/*Add Environment Variable:
Ldap:BindDn and Ldap:BindPassword for Windows container
Ldap__BindDn and Ldap__BindPassword for Linux container
*/
"Ldap": {
"Url": "ldap://172.16.0.10:389/OU=深圳冰川,DC=q1oa,DC=com"
},
"UserContext": {
"homePage": "http://www.dev.q1op.com/",
"logoutUrl": "http://auth-permit.dev.q1op.com/#/logout?rediret="
},
"AppSettings": {
"GameAreaApiUrl": "http://api.q1oa.com/ControlCenter/GameArea.asmx/GetList?GameCenterKey={0}",
"GameWorldApiUrl": "http://api.q1oa.com/ControlCenter/GameWorld.asmx/GetList?GameCenterKey={0}",
"CacheRefreshInterval": 5, //Game Area/World 缓存刷新间隔(In minutes)
"MqBusinessSend": "ActivityMgmtTx", // Send request to Socket Server
"MqBusinessRecv": "ActivityMgmtRx" // Get response from Socket Server
}
}
