Browse Source

First Commit

HOME 2 years ago
parent
commit
fac71292b3

+ 116 - 0
VCommonCoreExample.sln

@@ -0,0 +1,116 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31005.135
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Frameworks", "Frameworks", "{4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon", "..\VCommonCore\VCommon\VCommon.csproj", "{D2CABD4D-83F8-453F-8E13-9253D40D0994}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.Ioc", "..\VCommonCore\VCommon.Ioc\VCommon.Ioc.csproj", "{47FFC41E-CE42-4D0B-AB8B-62147BDA61DB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VAutoMapper", "..\VCommonCore\VCommon.VAutoMapper\VCommon.VAutoMapper.csproj", "{8C358174-BF11-4BF8-9491-F878CB04E2BF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.Json", "..\VCommonCore\VCommon.Json\VCommon.Json.csproj", "{CD5838B0-0B69-488E-AE7D-5E4809F050FA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VEntity", "..\VCommonCore\VCommon.VEntity\VCommon.VEntity.csproj", "{9A7B06B9-A18C-44B9-B6CC-8BEC0087D090}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VEntityFrameworkCore", "..\VCommonCore\VCommon.VEntityFrameworkCore\VCommon.VEntityFrameworkCore.csproj", "{B23E8534-61CE-4246-89EC-CE2DE1FE3085}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VOpenApi", "..\VCommonCore\VCommon.VOpenApi\VCommon.VOpenApi.csproj", "{53FD01C1-AD97-4E80-B730-82D9E6D39DCE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VOpenApi.VAspNetCore", "..\VCommonCore\VCommon.VOpenApi.VAspNetCore\VCommon.VOpenApi.VAspNetCore.csproj", "{A2247608-155B-4696-9F5D-57C9A3389542}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VSwaggerUI", "..\VCommonCore\VCommon.VSwaggerUI\VCommon.VSwaggerUI.csproj", "{E5497B35-5906-4E03-80F8-399C765FE8AD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VSwaggerUI.VAspNetCore", "..\VCommonCore\VCommon.VSwaggerUI.VAspNetCore\VCommon.VSwaggerUI.VAspNetCore.csproj", "{D8AF9EB7-EFF5-4D92-85FD-B4CF95CAB9B6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.VApplication", "..\VCommonCore\VCommon.VApplication\VCommon.VApplication.csproj", "{83698ED5-6F6F-4C04-9208-04C97DF4A33B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExampleProject", "ExampleProject", "{EE81EDCD-8A7D-4937-B62F-1807C012871C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VCommonCoreExample", "VCommonCoreExample\VCommonCoreExample.csproj", "{DC736024-C547-4E44-B9E4-D871F399FA9B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VCommon.Logging", "..\VCommonCore\VCommon.Logging\VCommon.Logging.csproj", "{84F5544F-2551-4A34-8C8A-E0E1F123C91C}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{D2CABD4D-83F8-453F-8E13-9253D40D0994}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D2CABD4D-83F8-453F-8E13-9253D40D0994}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D2CABD4D-83F8-453F-8E13-9253D40D0994}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D2CABD4D-83F8-453F-8E13-9253D40D0994}.Release|Any CPU.Build.0 = Release|Any CPU
+		{47FFC41E-CE42-4D0B-AB8B-62147BDA61DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{47FFC41E-CE42-4D0B-AB8B-62147BDA61DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{47FFC41E-CE42-4D0B-AB8B-62147BDA61DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{47FFC41E-CE42-4D0B-AB8B-62147BDA61DB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{8C358174-BF11-4BF8-9491-F878CB04E2BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{8C358174-BF11-4BF8-9491-F878CB04E2BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8C358174-BF11-4BF8-9491-F878CB04E2BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{8C358174-BF11-4BF8-9491-F878CB04E2BF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CD5838B0-0B69-488E-AE7D-5E4809F050FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CD5838B0-0B69-488E-AE7D-5E4809F050FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CD5838B0-0B69-488E-AE7D-5E4809F050FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CD5838B0-0B69-488E-AE7D-5E4809F050FA}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9A7B06B9-A18C-44B9-B6CC-8BEC0087D090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9A7B06B9-A18C-44B9-B6CC-8BEC0087D090}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9A7B06B9-A18C-44B9-B6CC-8BEC0087D090}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9A7B06B9-A18C-44B9-B6CC-8BEC0087D090}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B23E8534-61CE-4246-89EC-CE2DE1FE3085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B23E8534-61CE-4246-89EC-CE2DE1FE3085}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B23E8534-61CE-4246-89EC-CE2DE1FE3085}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B23E8534-61CE-4246-89EC-CE2DE1FE3085}.Release|Any CPU.Build.0 = Release|Any CPU
+		{53FD01C1-AD97-4E80-B730-82D9E6D39DCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{53FD01C1-AD97-4E80-B730-82D9E6D39DCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{53FD01C1-AD97-4E80-B730-82D9E6D39DCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{53FD01C1-AD97-4E80-B730-82D9E6D39DCE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A2247608-155B-4696-9F5D-57C9A3389542}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A2247608-155B-4696-9F5D-57C9A3389542}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A2247608-155B-4696-9F5D-57C9A3389542}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A2247608-155B-4696-9F5D-57C9A3389542}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E5497B35-5906-4E03-80F8-399C765FE8AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E5497B35-5906-4E03-80F8-399C765FE8AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E5497B35-5906-4E03-80F8-399C765FE8AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E5497B35-5906-4E03-80F8-399C765FE8AD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D8AF9EB7-EFF5-4D92-85FD-B4CF95CAB9B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D8AF9EB7-EFF5-4D92-85FD-B4CF95CAB9B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D8AF9EB7-EFF5-4D92-85FD-B4CF95CAB9B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D8AF9EB7-EFF5-4D92-85FD-B4CF95CAB9B6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{83698ED5-6F6F-4C04-9208-04C97DF4A33B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{83698ED5-6F6F-4C04-9208-04C97DF4A33B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{83698ED5-6F6F-4C04-9208-04C97DF4A33B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{83698ED5-6F6F-4C04-9208-04C97DF4A33B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DC736024-C547-4E44-B9E4-D871F399FA9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DC736024-C547-4E44-B9E4-D871F399FA9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DC736024-C547-4E44-B9E4-D871F399FA9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DC736024-C547-4E44-B9E4-D871F399FA9B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{84F5544F-2551-4A34-8C8A-E0E1F123C91C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{84F5544F-2551-4A34-8C8A-E0E1F123C91C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{84F5544F-2551-4A34-8C8A-E0E1F123C91C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{84F5544F-2551-4A34-8C8A-E0E1F123C91C}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{D2CABD4D-83F8-453F-8E13-9253D40D0994} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{47FFC41E-CE42-4D0B-AB8B-62147BDA61DB} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{8C358174-BF11-4BF8-9491-F878CB04E2BF} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{CD5838B0-0B69-488E-AE7D-5E4809F050FA} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{9A7B06B9-A18C-44B9-B6CC-8BEC0087D090} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{B23E8534-61CE-4246-89EC-CE2DE1FE3085} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{53FD01C1-AD97-4E80-B730-82D9E6D39DCE} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{A2247608-155B-4696-9F5D-57C9A3389542} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{E5497B35-5906-4E03-80F8-399C765FE8AD} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{D8AF9EB7-EFF5-4D92-85FD-B4CF95CAB9B6} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{83698ED5-6F6F-4C04-9208-04C97DF4A33B} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+		{DC736024-C547-4E44-B9E4-D871F399FA9B} = {EE81EDCD-8A7D-4937-B62F-1807C012871C}
+		{84F5544F-2551-4A34-8C8A-E0E1F123C91C} = {4E988382-1B5A-4173-A3E1-EDFD0C19E6D6}
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {82ED8AEA-C1C9-4245-8196-FAF9791294A1}
+	EndGlobalSection
+EndGlobal

+ 10 - 0
VCommonCoreExample/AppServices/Basic/AppServiceBase.cs

@@ -0,0 +1,10 @@
+using VCommon.Ioc;
+using VCommon.VApplication;
+using VCommonCoreExample.Audit;
+
+namespace VCommonCoreExample.AppServices.Basic
+{
+    public class AppServiceBase : ApplicationServiceBase, ITransientIocClass<ServiceAuditInterceptor>
+    {
+    }
+}

+ 12 - 0
VCommonCoreExample/AppServices/Basic/DbAppServiceBase.cs

@@ -0,0 +1,12 @@
+using VCommon.Ioc;
+using VCommon.VApplication;
+using VCommonCoreExample.Audit;
+using VCommonCoreExample.EntityFrameworkCore;
+
+namespace VCommonCoreExample.AppServices.Basic
+{
+    public class DbAppServiceBase : AppServiceBase
+    {
+        protected ExampleDbContext GetDbContext() => IocManager.Resolve<ExampleDbContext>();
+    }
+}

+ 31 - 0
VCommonCoreExample/AppServices/Session/Dto.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using VCommon.VApplication.Auditing.DataAnnotations;
+
+namespace VCommonCoreExample.AppServices.Session
+{
+    public class SessionLoginInput
+    {
+        [Required]
+        public string TenantCode { get; set; }
+
+        [Required]
+        public string LoginName { get; set; }
+
+        [Required, DisableAuditingLog]
+        public string Password { get; set; }
+
+        [Required]
+        public bool? Remember { get; set; }
+    }
+
+    public class SessionOutput
+    {
+        public string Token { get; set; }
+        public Guid UserId { get; set; }
+        public string UserName { get; set; }
+        public string[] Permissions { get; set; }
+        public IReadOnlyDictionary<string, object> Setting { get; set; }
+    }
+}

+ 34 - 0
VCommonCoreExample/AppServices/Session/SessionService.cs

@@ -0,0 +1,34 @@
+using VCommon.VApplication.Authorization;
+using VCommonCoreExample.AppServices.Basic;
+
+namespace VCommonCoreExample.AppServices.Session
+{
+    public interface ISessionService
+    {
+        SessionOutput Login(SessionLoginInput input);
+
+        [VServiceAuthorize]
+        void Logout();
+
+        [VServiceAuthorize]
+        SessionOutput GetSession();
+    }
+
+    public class SessionService : DbAppServiceBase, ISessionService
+    {
+        SessionOutput ISessionService.Login(SessionLoginInput input)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        SessionOutput ISessionService.GetSession()
+        {
+            throw new System.NotImplementedException();
+        }
+
+        void ISessionService.Logout()
+        {
+            throw new System.NotImplementedException();
+        }
+    }
+}

+ 25 - 0
VCommonCoreExample/Audit/ServiceAuditInterceptor.cs

@@ -0,0 +1,25 @@
+using System;
+using VCommon.Logging;
+using VCommon.VApplication.Auditing.Json;
+
+namespace VCommonCoreExample.Audit
+{
+    public class ServiceAuditInterceptor : JsonApplicationServiceAuditInterceptorBase
+    {
+        protected override void WriteJsonAuditLog(Guid? tenantId, Guid? userId, string serviceClassName, string serviceMethodName, string input, string output, string exception)
+        {
+            Logger.Trace("Audit", new
+            {
+                InvokeTiming.BeginInvokeTime,
+                InvokeTiming.Elapsed.TotalMilliseconds,
+                tenantId,
+                userId,
+                serviceClassName,
+                serviceMethodName,
+                Input = VJsonLogSerializer.Instance.DeserializeObject<object>(input),
+                Output = VJsonLogSerializer.Instance.DeserializeObject<object>(output),
+                Exception = VJsonLogSerializer.Instance.DeserializeObject<object>(exception)
+            });
+        }
+    }
+}

+ 46 - 0
VCommonCoreExample/Configuration/AppConfigurations.cs

@@ -0,0 +1,46 @@
+using System.Collections.Concurrent;
+using Microsoft.Extensions.Configuration;
+using VCommon;
+
+namespace VCommonCoreExample.Configuration
+{
+    public static class AppConfigurations
+    {
+        private static readonly ConcurrentDictionary<string, IConfigurationRoot> _configurationCache;
+
+        static AppConfigurations()
+        {
+            _configurationCache = new ConcurrentDictionary<string, IConfigurationRoot>();
+        }
+
+        public static IConfigurationRoot Get(string path, string environmentName = null, bool addUserSecrets = false)
+        {
+            var cacheKey = path + "#" + environmentName + "#" + addUserSecrets;
+            return _configurationCache.GetOrAdd(
+                cacheKey,
+                _ => BuildConfiguration(path, environmentName, addUserSecrets)
+            );
+        }
+
+        private static IConfigurationRoot BuildConfiguration(string path, string environmentName = null, bool addUserSecrets = false)
+        {
+            var builder = new ConfigurationBuilder()
+                .SetBasePath(path)
+                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
+
+            if (!environmentName.IsNullOrWhiteSpace())
+            {
+                builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true);
+            }
+
+            builder = builder.AddEnvironmentVariables();
+
+            if (addUserSecrets)
+            {
+                builder.AddUserSecrets(typeof(AppConfigurations).Assembly);
+            }
+
+            return builder.Build();
+        }
+    }
+}

+ 14 - 0
VCommonCoreExample/Configuration/HostingEnvironmentExtensions.cs

@@ -0,0 +1,14 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+
+namespace VCommonCoreExample.Configuration
+{
+    public static class HostingEnvironmentExtensions
+    {
+        public static IConfigurationRoot GetAppConfiguration(this IWebHostEnvironment env)
+        {
+            return AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName);
+        }
+    }
+}

+ 7 - 0
VCommonCoreExample/Configuration/ProjectConst.cs

@@ -0,0 +1,7 @@
+namespace VCommonCoreExample.Configuration
+{
+    public static class ProjectConst
+    {
+        public const string ConnectionStringName = "Default";
+    }
+}

+ 12 - 0
VCommonCoreExample/EntityFrameworkCore/ExampleDbContext.cs

@@ -0,0 +1,12 @@
+using Microsoft.EntityFrameworkCore;
+using VCommon.VApplication.EntityFrameworkCore;
+
+namespace VCommonCoreExample.EntityFrameworkCore
+{
+    public class ExampleDbContext : VAppDbContextBase
+    {
+        public ExampleDbContext(DbContextOptions<ExampleDbContext> options) : base(options)
+        {
+        }
+    }
+}

+ 12 - 0
VCommonCoreExample/EntityFrameworkCore/ExampleDbContextConfig.cs

@@ -0,0 +1,12 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace VCommonCoreExample.EntityFrameworkCore
+{
+    public static class ExampleDbContextConfig
+    {
+        public static void Configure(DbContextOptionsBuilder<ExampleDbContext> builder, string connectionString)
+        {
+            builder.UseMySQL(connectionString);
+        }
+    }
+}

+ 23 - 0
VCommonCoreExample/EntityFrameworkCore/ExampleDbContextFactory.cs

@@ -0,0 +1,23 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+using Microsoft.Extensions.Configuration;
+using VCommonCoreExample.Configuration;
+
+namespace VCommonCoreExample.EntityFrameworkCore
+{
+    /* This class is needed to run "dotnet ef ..." commands from command line on development. Not used anywhere else */
+
+    public class ExampleDbContextFactory : IDesignTimeDbContextFactory<ExampleDbContext>
+    {
+        public ExampleDbContext CreateDbContext(string[] args)
+        {
+            var builder = new DbContextOptionsBuilder<ExampleDbContext>();
+
+            var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
+
+            ExampleDbContextConfig.Configure(builder, configuration.GetConnectionString(ProjectConst.ConnectionStringName));
+
+            return new ExampleDbContext(builder.Options);
+        }
+    }
+}

+ 26 - 0
VCommonCoreExample/Program.cs

@@ -0,0 +1,26 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace VCommonCoreExample
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseStartup<Startup>();
+                });
+    }
+}

+ 28 - 0
VCommonCoreExample/Properties/launchSettings.json

@@ -0,0 +1,28 @@
+{
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:20919",
+      "sslPort": 0
+    }
+  },
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "VCommonCoreExample": {
+      "commandName": "Project",
+      "dotnetRunMessages": "true",
+      "launchBrowser": true,
+      "applicationUrl": "http://localhost:5000",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 12 - 0
VCommonCoreExample/SmpleInProcessCache/Caches.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace VCommonCoreExample.SmpleInProcessCache
+{
+    public static class Caches
+    {
+
+    }
+}

+ 78 - 0
VCommonCoreExample/Startup.cs

@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using VCommon.Ioc;
+using VCommon.Logging;
+using VCommon.VOpenApi.VAspNetCore;
+using VCommon.VSwaggerUI;
+using VCommon.VSwaggerUI.VAspNetCore;
+using VCommonCoreExample.AppServices.Session;
+using VCommonCoreExample.Configuration;
+using VCommonCoreExample.EntityFrameworkCore;
+
+namespace VCommonCoreExample
+{
+    public class Startup
+    {
+        private readonly IConfigurationRoot _appConfiguration;
+        private readonly string _contentRootPath;
+
+        public Startup(IWebHostEnvironment env)
+        {
+            _contentRootPath = env.ContentRootPath;
+            _appConfiguration = env.GetAppConfiguration();
+        }
+
+        // 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)
+        {
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            var dbg = false;
+
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+                dbg = true;
+            }
+
+            Logger.Init(new VJsonFileLogger(enableAll: dbg));
+            Logger.EnableDebugLevel = dbg;
+            Logger.Info("Application Init");
+
+            AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
+            {
+                Logger.Fatal("AppDomain.CurrentDomain.UnhandledException", e);
+            };
+
+            var connectionString = _appConfiguration.GetConnectionString(ProjectConst.ConnectionStringName);
+            var dbContextOptionsBuilder = new DbContextOptionsBuilder<ExampleDbContext>();
+            ExampleDbContextConfig.Configure(dbContextOptionsBuilder, connectionString);
+
+            var rootContainer = new IocManager();
+            rootContainer.RegisterInstanceToContainer(dbContextOptionsBuilder.Options);
+
+            if (dbg) app.UseSwaggerUiMiddleware(SwaggerUiResourceProvider.Version1);
+
+            ApiMiddleware.Init(new Dictionary<string, Type>
+            {
+                {"Session",typeof(ISessionService) }
+            }, iocManager: rootContainer, docGen: dbg, isDebuggingEnabled: dbg);
+
+            app.UseMiddleware<ApiMiddleware>();
+
+            Logger.Info("Application Init Done");
+        }
+    }
+}

+ 24 - 0
VCommonCoreExample/VCommonCoreExample.csproj

@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.7" />
+    <PackageReference Include="MySql.EntityFrameworkCore" Version="5.0.3.1" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\VCommonCore\VCommon.Logging\VCommon.Logging.csproj" />
+    <ProjectReference Include="..\..\VCommonCore\VCommon.VApplication\VCommon.VApplication.csproj" />
+    <ProjectReference Include="..\..\VCommonCore\VCommon.VOpenApi.VAspNetCore\VCommon.VOpenApi.VAspNetCore.csproj" />
+    <ProjectReference Include="..\..\VCommonCore\VCommon.VSwaggerUI.VAspNetCore\VCommon.VSwaggerUI.VAspNetCore.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="Authorization\" />
+    <Folder Include="Entity\" />
+  </ItemGroup>
+
+</Project>

+ 34 - 0
VCommonCoreExample/VSession.cs

@@ -0,0 +1,34 @@
+using System;
+using Microsoft.AspNetCore.Http;
+using VCommon.Ioc;
+using VCommon.VApplication;
+
+namespace VCommonCoreExample
+{
+    public class VSession : IVSession, ITransientIocClass
+    {
+        public VSession(HttpContext ctx)
+        {
+            //extract token
+            //and hold in context items?
+        }
+
+        public Guid GetTenantId()
+        {
+            throw new NotImplementedException();
+        }
+
+        public Guid GetUserId()
+        {
+            throw new NotImplementedException();
+        }
+
+        public string Token { get; set; }
+        public Guid? UserId { get; }
+        public Guid? TenantId { get; }
+        public void DemandAuth()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 47 - 0
VCommonCoreExample/WebContentFolderHelper.cs

@@ -0,0 +1,47 @@
+using System;
+using System.IO;
+using System.Linq;
+
+namespace VCommonCoreExample
+{
+    /// <summary>
+    /// This class is used to find root path of the web project in;
+    /// unit tests (to find views) and entity framework core command line commands (to find conn string).
+    /// </summary>
+    public static class WebContentDirectoryFinder
+    {
+        public static string CalculateContentRootFolder()
+        {
+            var coreAssemblyDirectoryPath = Path.GetDirectoryName(typeof(WebContentDirectoryFinder).Assembly.Location);
+            if (coreAssemblyDirectoryPath == null)
+            {
+                throw new Exception("Could not find location of VCommonCoreExample assembly!");
+            }
+
+            var directoryInfo = new DirectoryInfo(coreAssemblyDirectoryPath);
+            while (!DirectoryContains(directoryInfo.FullName, "VCommonCoreExample.sln"))
+            {
+                directoryInfo = directoryInfo.Parent ?? throw new Exception("Could not find content root folder!");
+            }
+
+            var webMvcFolder = Path.Combine(directoryInfo.FullName, "VCommonCoreExample");
+            if (Directory.Exists(webMvcFolder))
+            {
+                return webMvcFolder;
+            }
+
+            var webHostFolder = Path.Combine(directoryInfo.FullName, "VCommonCoreExample");
+            if (Directory.Exists(webHostFolder))
+            {
+                return webHostFolder;
+            }
+
+            throw new Exception("Could not find root folder of the web project!");
+        }
+
+        private static bool DirectoryContains(string directory, string fileName)
+        {
+            return Directory.GetFiles(directory).Any(filePath => string.Equals(Path.GetFileName(filePath), fileName));
+        }
+    }
+}

+ 3 - 0
VCommonCoreExample/appsettings.Development.json

@@ -0,0 +1,3 @@
+{
+
+}

+ 5 - 0
VCommonCoreExample/appsettings.json

@@ -0,0 +1,5 @@
+{
+  "ConnectionStrings": {
+    "Default": "server=DevEnvMySQL;port=3308;uid=root;database=VCommonCoreExample"
+  }
+}