diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs new file mode 100644 index 0000000..aa13d6f --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs @@ -0,0 +1,23 @@ +using Microsoft.AspNetCore.TestHost; +namespace EasyMicroservices.Cores.AspCore.Tests +{ + public class BasicTests + { + protected TestServer _testServer; + public BasicTests() + { + var webBuilder = new WebHostBuilder(); + webBuilder.UseStartup(); + + _testServer = new TestServer(webBuilder); + } + + [Theory] + [InlineData("/")] + public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url) + { + var client = _testServer.CreateClient(); + var data = await client.GetStringAsync($"api/user/getall"); + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserController.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserController.cs new file mode 100644 index 0000000..719b296 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserController.cs @@ -0,0 +1,14 @@ +using EasyMicroservices.Cores.AspCoreApi; +using EasyMicroservices.Cores.Database.Interfaces; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; +using Microsoft.AspNetCore.Mvc; + +namespace EasyMicroservices.Cores.AspCore.Tests.Controllers +{ + public class UserController : SimpleQueryServiceController + { + public UserController(IContractLogic contractLogic) : base(contractLogic) + { + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/EasyMicroservices.Cores.AspCore.Tests.csproj b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/EasyMicroservices.Cores.AspCore.Tests.csproj new file mode 100644 index 0000000..5342c33 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/EasyMicroservices.Cores.AspCore.Tests.csproj @@ -0,0 +1,31 @@ + + + + net7.0 + enable + false + false + latest + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + 7.0.10 + + + + diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs new file mode 100644 index 0000000..11b15b1 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs @@ -0,0 +1,32 @@ +using EasyMicroservices.Cores.AspEntityFrameworkCoreApi; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Intrerfaces; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Contexts; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; +using Microsoft.EntityFrameworkCore; + +namespace EasyMicroservices.Cores.AspCore.Tests +{ + public class Program + { + public static async Task Main(string[] args) + { + var app = StartUpExtensions.Create(args); + app.Services.Builder(); + app.Services.AddScoped((serviceProvider) => new UnitOfWork(serviceProvider).GetContractLogic()); + app.Services.AddTransient(serviceProvider => new MyTestContext(serviceProvider.GetService())); + app.Services.AddScoped(serviceProvider => new DatabaseBuilder()); + + var build = app.Build(); + build.MapControllers(); + build.Run(); + } + } + + public class DatabaseBuilder : IEntityFrameworkCoreDatabaseBuilder + { + public void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseInMemoryDatabase("Test DB"); + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Properties/launchSettings.json b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Properties/launchSettings.json new file mode 100644 index 0000000..85bbfe1 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Properties/launchSettings.json @@ -0,0 +1,42 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:4564" + }, + "https": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_URLS": "http://localhost:4564" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:4564" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:21417", + "sslPort": 44358 + } + } +} \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs new file mode 100644 index 0000000..85a0523 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs @@ -0,0 +1,39 @@ +using EasyMicroservices.Cores.AspEntityFrameworkCoreApi; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Intrerfaces; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Contexts; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; + +namespace EasyMicroservices.Cores.AspCore.Tests +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + public void ConfigureServices(IServiceCollection services) + { + UnitOfWork.DefaultUniqueIdentity = "1-2"; + UnitOfWork.MicroserviceId = 1250; + StartUpExtensions.Builder(services); + services.AddScoped((serviceProvider) => new UnitOfWork(serviceProvider).GetContractLogic()); + services.AddTransient(serviceProvider => new MyTestContext(serviceProvider.GetService())); + services.AddScoped(serviceProvider => new DatabaseBuilder()); + + //services.AddMvc().AddApplicationPart(typeof(UserController).Assembly).AddControllersAsServices(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + app.Build(); + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Usings.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Usings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.Development.json b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json new file mode 100644 index 0000000..44543c8 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json @@ -0,0 +1,16 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ConnectionStrings": { + "local": "connection string" + }, + "RootAddresses": { + "WhiteLabel": "http://localhost:1041" + }, + "AllowedHosts": "*", + "Urls": "http://*:4564" +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj index efea076..3476f59 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj @@ -5,7 +5,7 @@ AnyCPU;x64;x86 EasyMicroservices true - 0.0.0.19 + 0.0.0.20 asp core servces. EasyMicroservices@gmail.com core,cores,base,database,services,asp,aspnet diff --git a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj new file mode 100644 index 0000000..5d64ad7 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj @@ -0,0 +1,31 @@ + + + + net6.0;net7.0 + AnyCPU;x64;x86 + EasyMicroservices + true + 0.0.0.1 + asp core servces. + EasyMicroservices@gmail.com + core,cores,base,database,services,asp,aspnet,aspcore,efcore + https://github.com/EasyMicroservices/Cores + latest + true + .\bin\$(Configuration)\$(TargetFramework)\EasyMicroservices.Cores.AspEntityFrameworkCoreApi.xml + false + + + + + + + + + + + + + + + diff --git a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/Interfaces/IUnitOfWork.cs b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/Interfaces/IUnitOfWork.cs new file mode 100644 index 0000000..d31c292 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/Interfaces/IUnitOfWork.cs @@ -0,0 +1,36 @@ +using EasyMicroservices.Cores.Database.Interfaces; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore; +using EasyMicroservices.Database.Interfaces; +using EasyMicroservices.Mapper.Interfaces; +using System; + +namespace EasyMicroservices.Cores.AspEntityFrameworkCoreApi.Interfaces +{ + /// + /// + /// + public interface IUnitOfWork : IDisposable, IAsyncDisposable + { + /// + /// + /// + /// + IDatabase GetDatabase(); + /// + /// + /// + /// + IDatabase GetDatabase() + where TContext : RelationalCoreContext; + /// + /// + /// + /// + IMapperProvider GetMapper(); + /// + /// + /// + /// + IUniqueIdentityManager GetUniqueIdentityManager(); + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/StartUpExtensions.cs b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/StartUpExtensions.cs new file mode 100644 index 0000000..365f78e --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/StartUpExtensions.cs @@ -0,0 +1,145 @@ +using EasyMicroservices.Cores.AspEntityFrameworkCoreApi.Interfaces; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Builders; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using System; +using System.Linq; + +namespace EasyMicroservices.Cores.AspEntityFrameworkCoreApi +{ + /// + /// + /// + public static class StartUpExtensions + { + /// + /// + /// + /// + /// + /// + public static WebApplicationBuilder Create(string[] args) + { + return WebApplication.CreateBuilder(args); + } + + /// + /// + /// + /// + /// + public static IServiceCollection Builder(this IServiceCollection services) + where TContext : RelationalCoreContext + { + + // Add services to the container. + //builder.Services.AddAuthorization(); + services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + services.AddEndpointsApiExplorer(); + services.AddSwaggerGen(options => + { + options.SchemaFilter(); + options.SchemaFilter(); + }); + + services.AddHttpContextAccessor(); + services.AddScoped(service => new UnitOfWork(service)); + services.AddScoped(service => new UnitOfWork(service).GetMapper()); + services.AddTransient(serviceProvider => serviceProvider.GetService()); + return services; + } + + /// + /// + /// + /// + /// + /// + public static void Build(this IApplicationBuilder app) + where TContext : RelationalCoreContext + { + var build = app.Build(); + app.UseDeveloperExceptionPage(); + // Configure the HTTP request pipeline. + app.UseSwagger(); + app.UseSwaggerUI(); + + app.UseHttpsRedirection(); + app.UseAuthorization(); + //app.MapControllers(); + //app.Run(build); + using (var scope = app.ApplicationServices.CreateAsyncScope()) + { + var dbbuilder = new DatabaseCreator(); + using var context = scope.ServiceProvider.GetRequiredService(); + dbbuilder.Initialize(context); + } + app.Run(build); + } + + /// + /// + /// + /// + /// + /// + public static WebApplication Build(this WebApplicationBuilder app) + where TContext : RelationalCoreContext + { + var build = app.Build(); + build.UseDeveloperExceptionPage(); + // Configure the HTTP request pipeline. + build.UseSwagger(); + build.UseSwaggerUI(); + + build.UseHttpsRedirection(); + build.UseAuthorization(); + //app.MapControllers(); + //app.Run(build); + using (var scope = build.Services.CreateAsyncScope()) + { + var dbbuilder = new DatabaseCreator(); + using var context = scope.ServiceProvider.GetRequiredService(); + dbbuilder.Initialize(context); + } + return build; + } + } +} + + +internal class GenericFilter : ISchemaFilter +{ + public void Apply(OpenApiSchema schema, SchemaFilterContext context) + { + var type = context.Type; + + if (type.IsGenericType == false) + return; + + schema.Title = $"{type.Name[0..^2]}<{type.GenericTypeArguments[0].Name}>"; + } +} + +internal class XEnumNamesSchemaFilter : ISchemaFilter +{ + private const string NAME = "x-enumNames"; + public void Apply(OpenApiSchema model, SchemaFilterContext context) + { + var typeInfo = context.Type; + // Chances are something in the pipeline might generate this automatically at some point in the future + // therefore it's best to check if it exists. + if (typeInfo.IsEnum && !model.Extensions.ContainsKey(NAME)) + { + var names = Enum.GetNames(context.Type); + var arr = new OpenApiArray(); + arr.AddRange(names.Select(name => new OpenApiString(name))); + model.Extensions.Add(NAME, arr); + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/UnitOfWork.cs b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/UnitOfWork.cs new file mode 100644 index 0000000..3b3ad20 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/UnitOfWork.cs @@ -0,0 +1,173 @@ +using EasyMicroservices.Cores.AspEntityFrameworkCoreApi.Interfaces; +using EasyMicroservices.Cores.Database.Interfaces; +using EasyMicroservices.Cores.Database.Logics; +using EasyMicroservices.Cores.Database.Managers; +using EasyMicroservices.Cores.Interfaces; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore; +using EasyMicroservices.Database.EntityFrameworkCore.Providers; +using EasyMicroservices.Database.Interfaces; +using EasyMicroservices.Mapper.CompileTimeMapper.Interfaces; +using EasyMicroservices.Mapper.CompileTimeMapper.Providers; +using EasyMicroservices.Mapper.Interfaces; +using EasyMicroservices.Mapper.SerializerMapper.Providers; +using EasyMicroservices.Serialization.Newtonsoft.Json.Providers; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EasyMicroservices.Cores.AspEntityFrameworkCoreApi +{ + /// + /// + /// + public class UnitOfWork : IUnitOfWork + { + /// + /// + /// + public static Type MapperTypeAssembly { get; set; } + IServiceProvider _service; + /// + /// + /// + /// + public UnitOfWork(IServiceProvider service) + { + _service = service; + } + + List Disposables { get; set; } = new List(); + + T AddDisposable(T data) + { + Disposables.Add(data); + return data; + } + /// + /// + /// + /// + public IDatabase GetDatabase() + { + return AddDisposable(new EntityFrameworkCoreDatabaseProvider(_service.GetService())); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public virtual IContractLogic GetContractLogic() + where TEntity : class, IIdSchema + where TResponseContract : class + { + return AddDisposable(new LongIdMappedDatabaseLogicBase(GetDatabase().GetReadableOf(), GetDatabase().GetWritableOf(), GetMapper(), GetUniqueIdentityManager())); + } + + /// + /// + /// + /// + /// + public virtual IEasyReadableQueryableAsync GetReadableQueryable() + where TEntity : class, IIdSchema + { + return GetDatabase().GetReadableOf(); + } + + /// + /// + /// + /// + /// + /// + public IDatabase GetDatabase() + where TContext : RelationalCoreContext + { + return AddDisposable(new EntityFrameworkCoreDatabaseProvider(_service.GetService())); + } + + /// + /// + /// + /// + /// + public IMapperProvider GetMapper() + { + var mapper = new CompileTimeMapperProvider(new SerializerMapperProvider(new NewtonsoftJsonProvider())); + if (MapperTypeAssembly != null) + { + foreach (var type in MapperTypeAssembly.Assembly.GetTypes()) + { + if (typeof(IMapper).IsAssignableFrom(type)) + { + var instance = Activator.CreateInstance(type, mapper); + var returnTypes = type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(x => x.ReturnType != typeof(object) && x.Name == "Map").Select(x => x.ReturnType).ToArray(); + mapper.AddMapper(returnTypes[0], returnTypes[1], (IMapper)instance); + } + } + } + return mapper; + } + + /// + /// + /// + public static string DefaultUniqueIdentity { get; set; } + /// + /// + /// + public static long MicroserviceId { get; set; } + /// + /// + /// + public static IUniqueIdentityManager UniqueIdentityManager { get; set; } + /// + /// + /// + /// + /// + public IUniqueIdentityManager GetUniqueIdentityManager() + { + if (UniqueIdentityManager == null) + UniqueIdentityManager = new DefaultUniqueIdentityManager(DefaultUniqueIdentity, MicroserviceId); + return UniqueIdentityManager; + } + + /// + /// + /// + /// + public void Dispose() + { + foreach (var item in Disposables) + { + if (item is IDisposable disposable) + { + disposable.Dispose(); + } + } + } + + /// + /// + /// + /// + public async ValueTask DisposeAsync() + { + foreach (var item in Disposables) + { + if (item is IAsyncDisposable disposable) + { + await disposable.DisposeAsync(); + } + } + Dispose(); + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/DeleteRequestContract.cs b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/DeleteRequestContract.cs index 5cebe8f..45bac78 100644 --- a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/DeleteRequestContract.cs +++ b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/DeleteRequestContract.cs @@ -14,5 +14,16 @@ public class DeleteRequestContract : IIdSchema /// /// public T Id { get; set; } + /// + /// + /// + /// + public static implicit operator DeleteRequestContract(T id) + { + return new DeleteRequestContract() + { + Id = id + }; + } } } diff --git a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetIdRequestContract.cs b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetIdRequestContract.cs index 224bac4..d582d13 100644 --- a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetIdRequestContract.cs +++ b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetIdRequestContract.cs @@ -12,5 +12,16 @@ public class GetIdRequestContract : IIdSchema /// /// public T Id { get; set; } + /// + /// + /// + /// + public static implicit operator GetIdRequestContract(T id) + { + return new GetIdRequestContract() + { + Id = id + }; + } } } diff --git a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetUniqueIdentityRequestContract.cs b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetUniqueIdentityRequestContract.cs index 418a64c..7528574 100644 --- a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetUniqueIdentityRequestContract.cs +++ b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/GetUniqueIdentityRequestContract.cs @@ -11,5 +11,16 @@ public class GetUniqueIdentityRequestContract : IUniqueIdentitySchema /// /// public string UniqueIdentity { get; set; } + /// + /// + /// + /// + public static implicit operator GetUniqueIdentityRequestContract(string uniqueIdentity) + { + return new GetUniqueIdentityRequestContract() + { + UniqueIdentity = uniqueIdentity + }; + } } } diff --git a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/SoftDeleteRequestContract.cs b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/SoftDeleteRequestContract.cs index 947f0c0..5ec03f0 100644 --- a/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/SoftDeleteRequestContract.cs +++ b/src/CSharp/EasyMicroservices.Cores.Contracts/Contracts/Requests/SoftDeleteRequestContract.cs @@ -9,5 +9,18 @@ public class SoftDeleteRequestContract : DeleteRequestContract /// /// public bool IsDelete { get; set; } + + /// + /// + /// + /// + public static implicit operator SoftDeleteRequestContract((T Id, bool IsDelete) values) + { + return new SoftDeleteRequestContract() + { + Id = values.Id, + IsDelete = values.IsDelete + }; + } } } diff --git a/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj b/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj index bde1388..e8ec004 100644 --- a/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj @@ -1,11 +1,11 @@ - + netstandard2.0;netstandard2.1;net6.0;net45 AnyCPU;x64;x86 EasyMicroservices true - 0.0.0.5 + 0.0.0.6 core contracts. EasyMicroservices@gmail.com core,cores,base,contract,contracts,dto,dtos @@ -21,4 +21,8 @@ + + + + diff --git a/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj b/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj index ba51aa8..2cfa1aa 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj @@ -5,7 +5,7 @@ AnyCPU;x64;x86 EasyMicroservices true - 0.0.0.21 + 0.0.0.22 core of database. EasyMicroservices@gmail.com core,cores,base,database diff --git a/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj b/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj index 2da7e8c..b654499 100644 --- a/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj +++ b/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj @@ -5,7 +5,7 @@ AnyCPU;x64;x86 EasyMicroservices true - 0.0.0.12 + 0.0.0.13 ef core of database. EasyMicroservices@gmail.com core,cores,base,database,ef,efcore diff --git a/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/Builders/DatabaseCreator.cs b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/Builders/DatabaseCreator.cs new file mode 100644 index 0000000..77bc8fb --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/Builders/DatabaseCreator.cs @@ -0,0 +1,62 @@ +using EasyMicroservices.Cores.EntityFrameworkCore; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Intrerfaces; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace EasyMicroservices.Cores.Relational.EntityFrameworkCore.Builders +{ + /// + /// + /// + public class DatabaseCreator + { + /// + /// + /// + /// + public void Initialize(CoreContext context) + { + if (context.Database.EnsureCreated()) + { + if (context.Database.ProviderName == "Microsoft.EntityFrameworkCore.InMemory") + return; + //auto migration when database created first time + + //add migration history table + + string createEFMigrationsHistoryCommand = $@" +USE [{context.Database.GetDbConnection().Database}]; +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; +CREATE TABLE [dbo].[__EFMigrationsHistory]( + [MigrationId] [nvarchar](150) NOT NULL, + [ProductVersion] [nvarchar](32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY CLUSTERED +( + [MigrationId] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY]; +"; + context.Database.ExecuteSqlRaw(createEFMigrationsHistoryCommand); + + //insert all of migrations + var dbAssebmly = context.GetType().Assembly; + foreach (var item in dbAssebmly.GetTypes()) + { + if (item.BaseType == typeof(Migration)) + { + string migrationName = item.GetCustomAttributes().First().Id; + var version = typeof(Migration).Assembly.GetName().Version; + string efVersion = $"{version.Major}.{version.Minor}.{version.Build}"; + context.Database.ExecuteSqlRaw("INSERT INTO __EFMigrationsHistory(MigrationId,ProductVersion) VALUES ({0},{1})", migrationName, efVersion); + } + } + } + context.Database.Migrate(); + } + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj index 99e3227..7d78d18 100644 --- a/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj @@ -5,7 +5,7 @@ AnyCPU;x64;x86 EasyMicroservices true - 0.0.0.9 + 0.0.0.10 ef core of Relational database. EasyMicroservices@gmail.com core,cores,base,database,ef,efcore,Relational diff --git a/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/Intrerfaces/IEntityFrameworkCoreDatabaseBuilder.cs b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/Intrerfaces/IEntityFrameworkCoreDatabaseBuilder.cs new file mode 100644 index 0000000..6b62ebb --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/Intrerfaces/IEntityFrameworkCoreDatabaseBuilder.cs @@ -0,0 +1,18 @@ +using EasyMicroservices.Cores.Database.Interfaces; +using EasyMicroservices.Cores.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; + +namespace EasyMicroservices.Cores.Relational.EntityFrameworkCore.Intrerfaces +{ + /// + /// + /// + public interface IEntityFrameworkCoreDatabaseBuilder + { + /// + /// + /// + /// + void OnConfiguring(DbContextOptionsBuilder optionsBuilder); + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Contexts/MyTestContext.cs b/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Contexts/MyTestContext.cs index ab9814c..a3dd628 100644 --- a/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Contexts/MyTestContext.cs +++ b/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Contexts/MyTestContext.cs @@ -1,14 +1,23 @@ -using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Intrerfaces; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; using Microsoft.EntityFrameworkCore; namespace EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Contexts { - public class MyTestContext : DbContext + public class MyTestContext : RelationalCoreContext { + IEntityFrameworkCoreDatabaseBuilder _builder; + public MyTestContext(IEntityFrameworkCoreDatabaseBuilder builder) + { + _builder = builder; + } + public DbSet Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseInMemoryDatabase("MyTestContext"); + if (_builder != null) + _builder.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder); } diff --git a/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/LongIdMappedDatabaseLogicBaseTest.cs b/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/LongIdMappedDatabaseLogicBaseTest.cs index 664ee60..6a6ac8c 100644 --- a/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/LongIdMappedDatabaseLogicBaseTest.cs +++ b/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/LongIdMappedDatabaseLogicBaseTest.cs @@ -2,6 +2,8 @@ using EasyMicroservices.Cores.Database.Interfaces; using EasyMicroservices.Cores.Database.Logics; using EasyMicroservices.Cores.Database.Managers; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Builders; +using EasyMicroservices.Cores.Relational.EntityFrameworkCore.Intrerfaces; using EasyMicroservices.Cores.Tests.Contracts.Common; using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Contexts; using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; @@ -11,9 +13,18 @@ using EasyMicroservices.Mapper.Interfaces; using EasyMicroservices.Mapper.SerializerMapper.Providers; using EasyMicroservices.ServiceContracts; +using Microsoft.EntityFrameworkCore; namespace EasyMicroservices.Cores.Tests.Database { + public class DatabaseBuilder : IEntityFrameworkCoreDatabaseBuilder + { + public void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseInMemoryDatabase("Test DB"); + } + } + public class LongIdMappedDatabaseLogicBaseTest { public LongIdMappedDatabaseLogicBaseTest() @@ -33,7 +44,7 @@ IContractLogic + diff --git a/src/CSharp/EasyMicroservices.Cores.sln b/src/CSharp/EasyMicroservices.Cores.sln index 5061757..62c8995 100644 --- a/src/CSharp/EasyMicroservices.Cores.sln +++ b/src/CSharp/EasyMicroservices.Cores.sln @@ -21,7 +21,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BusinessLogic-Layer", "Busi EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test-Layer", "Test-Layer", "{C2D086CC-9E2B-4152-B8F7-81E91032C17C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyMicroservices.Cores.Relational.EntityFrameworkCore", "EasyMicroservices.Cores.Relational.EntityFrameworkCore\EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj", "{2B4DE46B-911F-4C08-B506-B8D31A8B074B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyMicroservices.Cores.Relational.EntityFrameworkCore", "EasyMicroservices.Cores.Relational.EntityFrameworkCore\EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj", "{2B4DE46B-911F-4C08-B506-B8D31A8B074B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyMicroservices.Cores.AspEntityFrameworkCoreApi", "EasyMicroservices.Cores.AspEntityFrameworkCoreApi\EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj", "{2A012C31-966A-427B-B685-DCB95AC299E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyMicroservices.Cores.AspCore.Tests", "EasyMicroservices.Cores.AspCore.Tests\EasyMicroservices.Cores.AspCore.Tests.csproj", "{243E15A6-5AD6-4304-8F91-D12666C59A0E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -117,6 +121,30 @@ Global {2B4DE46B-911F-4C08-B506-B8D31A8B074B}.Release|x64.Build.0 = Release|Any CPU {2B4DE46B-911F-4C08-B506-B8D31A8B074B}.Release|x86.ActiveCfg = Release|Any CPU {2B4DE46B-911F-4C08-B506-B8D31A8B074B}.Release|x86.Build.0 = Release|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Debug|x64.ActiveCfg = Debug|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Debug|x64.Build.0 = Debug|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Debug|x86.ActiveCfg = Debug|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Debug|x86.Build.0 = Debug|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Release|Any CPU.Build.0 = Release|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Release|x64.ActiveCfg = Release|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Release|x64.Build.0 = Release|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Release|x86.ActiveCfg = Release|Any CPU + {2A012C31-966A-427B-B685-DCB95AC299E3}.Release|x86.Build.0 = Release|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Debug|x64.ActiveCfg = Debug|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Debug|x64.Build.0 = Debug|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Debug|x86.Build.0 = Debug|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Release|Any CPU.Build.0 = Release|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Release|x64.ActiveCfg = Release|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Release|x64.Build.0 = Release|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Release|x86.ActiveCfg = Release|Any CPU + {243E15A6-5AD6-4304-8F91-D12666C59A0E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -129,6 +157,8 @@ Global {2142912F-21AB-4A26-B9AF-F82BD9BE85EF} = {5F639C59-EF1C-464B-85F1-FE01E4A9F81A} {0EA879CC-3350-4B97-8517-DCE7DBD2C3CC} = {C2D086CC-9E2B-4152-B8F7-81E91032C17C} {2B4DE46B-911F-4C08-B506-B8D31A8B074B} = {B9CFFFCB-64BC-4E3A-982B-C50FEFE6EA9B} + {2A012C31-966A-427B-B685-DCB95AC299E3} = {5F639C59-EF1C-464B-85F1-FE01E4A9F81A} + {243E15A6-5AD6-4304-8F91-D12666C59A0E} = {C2D086CC-9E2B-4152-B8F7-81E91032C17C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0E8382C1-722C-4F92-B66F-0354487C7F02}