diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Controllers/HomeController.cs b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Controllers/HomeController.cs new file mode 100644 index 0000000000..66ab9f58d0 --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Controllers/HomeController.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace MyCompanyName.MyProjectName.Controllers +{ + public class HomeController : AbpController + { + public ActionResult Index() + { + return Redirect("/swagger"); + } + } +} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj index 423afacffc..640f10b201 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj @@ -1,13 +1,53 @@ - + + + netcoreapp2.2 - InProcess + MyCompanyName.MyProjectName + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + + + signed + + + + diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs new file mode 100644 index 0000000000..e07ffa4b9d --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs @@ -0,0 +1,138 @@ +using System.IO; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using MyCompanyName.MyProjectName.EntityFrameworkCore; +using MyCompanyName.MyProjectName.MultiTenancy; +using StackExchange.Redis; +using Swashbuckle.AspNetCore.Swagger; +using Volo.Abp; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Autofac; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace MyCompanyName.MyProjectName +{ + [DependsOn( + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(MyProjectNameHttpApiModule), + typeof(MyProjectNameApplicationModule), + typeof(MyProjectNameEntityFrameworkCoreModule) + )] + public class MyProjectNameHttpApiHostModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + ConfigureConventionalControllers(); + ConfigureAuthentication(context); + ConfigureSwagger(context); + ConfigureLocalization(); + ConfigureVirtualFileSystem(context); + ConfigureRedis(context, configuration, hostingEnvironment); + } + + private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + if (hostingEnvironment.IsDevelopment()) + { + Configure(options => + { + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain.Shared", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application", Path.DirectorySeparatorChar))); + }); + } + } + + private void ConfigureConventionalControllers() + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(MyProjectNameApplicationModule).Assembly); + }); + } + + private void ConfigureAuthentication(ServiceConfigurationContext context) + { + context.Services.AddAuthentication("Bearer") + .AddIdentityServerAuthentication(options => + { + options.Authority = "https://localhost:44348"; + options.RequireHttpsMetadata = true; + options.ApiName = "MyProjectName"; + }); + } + + private static void ConfigureSwagger(ServiceConfigurationContext context) + { + context.Services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new Info {Title = "MyProjectName API", Version = "v1"}); + options.DocInclusionPredicate((docName, description) => true); + }); + } + + private void ConfigureLocalization() + { + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); + options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + }); + } + + private void ConfigureRedis( + ServiceConfigurationContext context, + IConfigurationRoot configuration, + IHostingEnvironment hostingEnvironment) + { + context.Services.AddDistributedRedisCache(options => + { + options.Configuration = configuration["Redis:Configuration"]; + }); + + if (!hostingEnvironment.IsDevelopment()) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + context.Services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "MyProjectName-Protection-Keys"); + } + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + + app.UseVirtualFiles(); + app.UseAuthentication(); + if (MultiTenancyConsts.IsMultiTenancyEnabled) + { + app.UseMultiTenancy(); + } + app.UseAbpRequestLocalization(); + app.UseSwagger(); + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API"); + }); + app.UseAuditing(); + app.UseMvcWithDefaultRouteAndArea(); + } + } +} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs index e117c9ddb1..0a4250ea4d 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Program.cs @@ -1,24 +1,46 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; -namespace MyCompanyName.MyProjectName.HttpApi.Host +namespace MyCompanyName.MyProjectName { public class Program { - public static void Main(string[] args) + public static int Main(string[] args) { - CreateWebHostBuilder(args).Build().Run(); + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.FromLogContext() + .WriteTo.File("Logs/logs.txt") + .CreateLogger(); + + try + { + Log.Information("Starting MyCompanyName.MyProjectName.HttpApi.Host."); + BuildWebHostInternal(args).Run(); + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); + public static IWebHost BuildWebHostInternal(string[] args) => + new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .UseSerilog() + .Build(); } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs index e88891f5f2..19fe569013 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/Startup.cs @@ -1,34 +1,27 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Volo.Abp; -namespace MyCompanyName.MyProjectName.HttpApi.Host +namespace MyCompanyName.MyProjectName { public class Startup { - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) + public IServiceProvider ConfigureServices(IServiceCollection services) { + services.AddApplication(options => + { + options.UseAutofac(); + }); + + return services.BuildServiceProviderFromFactory(); } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.Run(async (context) => - { - await context.Response.WriteAsync("Hello World!"); - }); + app.InitializeApplication(); } } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.Development.json b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.Development.json index e203e9407e..2c63c08510 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.Development.json +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.Development.json @@ -1,9 +1,2 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json index def9159a7d..73ad9e7229 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/appsettings.json @@ -1,8 +1,8 @@ { - "Logging": { - "LogLevel": { - "Default": "Warning" - } + "ConnectionStrings": { + "Default": "Server=localhost;Database=MyProjectName;Trusted_Connection=True;MultipleActiveResultSets=true" }, - "AllowedHosts": "*" + "Redis": { + "Configuration": "127.0.0.1" + } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/tempkey.rsa b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/tempkey.rsa new file mode 100644 index 0000000000..ed0defa5a8 --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/tempkey.rsa @@ -0,0 +1 @@ +{"KeyId":"600caa200caf5d805eba9f06ace9e236","Parameters":{"D":"KCNDHA96eimN+UqchSKocgYITGflaAIwxzCS5KqSTkYAFliPthQx7LySuLor4F1+uLvwnh3ZocyI3y43GZu+eVHD256sxdV8/UsQz1HC23RRFqcUiAZjze8K5VMVStrBOxaa/Ds1U9/bpuNE7jZdcgFIEHsdZtCACqwtlE4nlIs1/GLiokqjBOESgxJMy9WUeDbWcvoo+YdwgKf5jt6AZHOYSS+TokLL+Y7TEfGMXe3jZD9VtSMkBSM8wGB89zNGR0FZB9maCG/BCoRJqxdYRyeb4FFXJclQtK3DexyDVqlNZQaNKVHu0tVAnVNKKcd7Iex8gA+5DNqqucUA7C/F6Q==","DP":"fr9iaNb1W4YZ/NJ56+N3SCeDQYuKobq1qeaQWmHlQsOHKoHhNZJQZ5x0M9PQilou16AwVlNGCJncMwxsSUxXn6itG0LcBnvfMeo2v3xKcij1BtFR9qfXecwEn2nnhI3mpXtZxyCdP3NIYUp9qViLJUjGJqrbQk+OIAGRQd2rRe0=","DQ":"o1umLkDodtwvpCsDguQYSjd3iob+WHNmfe/9HyjADmUehP8b9SpUgcrb+QF301J8YmQMnYZKWW5rEwKOtwsWNswgXfMnXeWerlZmz0tj9y38YczS70liU0vETsRefhrRCaXHraMvneqYNNedhsrCNalWK+DNwcixi4L59vA8ofs=","Exponent":"AQAB","InverseQ":"btd1nwwxl/E3ryfDi2bN12TuVDvv7yoPvryIlLgu+FiLpe4vaA1omDLliQBcl7oeyA563HBUop4D5oE7si+jD64N8XgFz37dD3KqUokeQ4lrTSSOePT1K+nWIl30sqDd7YE4auz4CvSjm2wXmN31+CXW1hp3YWN2972yrUt+R5U=","Modulus":"uwMB6reAVtm/Cq0BRPZ0ozBq6g3wDh2kzqFKBf8I7u8d9p7i5ExLSrOWPupHwPr/IW1VUn2TKHrJ8OnyYhznKIRxqlxj0U3D2GXijz5kfFOoHK+mlfKaDMqweRoS0UzEz58kMlgwUoDraUj6dTHTPCVPo3TqA2ImRw50j6D+jobFrY5321EFvlirZViMPDAgB8Ca7wGCqNBcCxvIPYw1O6WZmcVmjG7umelD3XjcUIQlEbIyAmi/3gXAo7NdPmgOamla6bnSWsy429HfsNpXyCfPBzV3QS3ubpTekWPoPcOVZbWwVPYtFQbhRh8PmWATRx0cV6oePZNZGxGeJl8WYQ==","P":"wplelBfVmiOPmr6iUxtOgIzuvwSqvP6Rqmh8dhaGDiJjU8OqZ0tZhuh0G+xnMLPIHb2fMeg0dqZMJZ5iXaIi1QycYn/JKz1i4cUonJ6IIQeKKf67tvzn/BY0V0N8rJw8hVfzou+/5sRBCbiHtJ2KIN1YJQuWGFFfrZJOJzc95ss=","Q":"9gTGKoDiOdrY8kqIXJ2nMhoeNryAH4q3EUrROJ7simqc28oYlGx24Sco/wOoeB2xxrdcF5JYOlyJ7H2YY/huLvJISaw/wHLPskiKiYQ78tuNwW0ip+5ceB1dSToHcEe3sR30+OeTh0Z4ZKoqthKziFGIt3EhEgiGq1gjZuWB5gM="}} \ No newline at end of file diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index 4d4731be38..d148cc21c0 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -89,10 +89,13 @@ namespace MyCompanyName.MyProjectName options.Configuration = configuration["Redis:Configuration"]; }); - //TODO: ConnectionMultiplexer.Connect call has problem since redis may not be ready when this service has started! - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - context.Services.AddDataProtection() - .PersistKeysToStackExchangeRedis(redis, "MyProjectName-Protection-Keys"); + if (!hostingEnvironment.IsDevelopment()) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + context.Services + .AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "MyProjectName-Protection-Keys"); + } } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs index fb82af9ed5..247990c584 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs @@ -58,9 +58,10 @@ namespace MyCompanyName.MyProjectName { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + ConfigureAutoMapper(); ConfigureVirtualFileSystem(hostingEnvironment); + ConfigureConventionalControllers(); ConfigureLocalizationServices(); ConfigureNavigationServices(); ConfigureAutoApiControllers(); @@ -101,6 +102,14 @@ namespace MyCompanyName.MyProjectName } } + private void ConfigureConventionalControllers() + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(MyProjectNameApplicationModule).Assembly); + }); + } + private void ConfigureLocalizationServices() { Configure(options =>