From b14d6c0f8f0a3cdf9e85e61dd9909eeb350ad570 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 10:43:51 -0500 Subject: [PATCH 01/12] chore: Add new nuget packages --- Directory.Packages.props | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 06e9176..ecc29fa 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,9 +3,14 @@ true + + + + + @@ -16,4 +21,4 @@ - + \ No newline at end of file From 2198f2dd6be83feafde06902d8c419ff6227ab7b Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 10:48:59 -0500 Subject: [PATCH 02/12] docs: Add samples on how to integrate YeSql.Net with plug-ins --- .../Contracts/IPluginStartup.cs | 8 +++ .../Contracts/PluginApp.Contracts.csproj | 12 ++++ samples/Example.PluginApp/Host/.env | 5 ++ .../Host/PluginApp.Host.csproj | 21 +++++++ samples/Example.PluginApp/Host/Program.cs | 62 +++++++++++++++++++ .../Host/Properties/launchSettings.json | 41 ++++++++++++ .../Example.PluginApp/Host/SqlController.cs | 13 ++++ samples/Example.PluginApp/Host/sample.sql | 2 + .../Plugins/Directory.Build.props | 21 +++++++ .../EmployeePlugin/EmployeeSqlController.cs | 12 ++++ .../EmployeePlugin/EmployeeSqlService.cs | 9 +++ .../PluginApp.EmployeePlugin.csproj | 9 +++ .../Plugins/EmployeePlugin/PluginStartup.cs | 15 +++++ .../Plugins/EmployeePlugin/employee.sql | 2 + .../Plugins/HelloPlugin/HelloController.cs | 12 ++++ .../Plugins/HelloPlugin/HelloService.cs | 7 +++ .../HelloPlugin/PluginApp.HelloPlugin.csproj | 9 +++ .../Plugins/HelloPlugin/PluginStartup.cs | 15 +++++ .../UserPlugin/PluginApp.UserPlugin.csproj | 9 +++ .../Plugins/UserPlugin/PluginStartup.cs | 15 +++++ .../Plugins/UserPlugin/UserSqlController.cs | 12 ++++ .../Plugins/UserPlugin/UserSqlService.cs | 9 +++ .../Plugins/UserPlugin/user.sql | 2 + samples/YeSql.Net.Examples.sln | 31 ++++++++++ 24 files changed, 353 insertions(+) create mode 100644 samples/Example.PluginApp/Contracts/IPluginStartup.cs create mode 100644 samples/Example.PluginApp/Contracts/PluginApp.Contracts.csproj create mode 100644 samples/Example.PluginApp/Host/.env create mode 100644 samples/Example.PluginApp/Host/PluginApp.Host.csproj create mode 100644 samples/Example.PluginApp/Host/Program.cs create mode 100644 samples/Example.PluginApp/Host/Properties/launchSettings.json create mode 100644 samples/Example.PluginApp/Host/SqlController.cs create mode 100644 samples/Example.PluginApp/Host/sample.sql create mode 100644 samples/Example.PluginApp/Plugins/Directory.Build.props create mode 100644 samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs create mode 100644 samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlService.cs create mode 100644 samples/Example.PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj create mode 100644 samples/Example.PluginApp/Plugins/EmployeePlugin/PluginStartup.cs create mode 100644 samples/Example.PluginApp/Plugins/EmployeePlugin/employee.sql create mode 100644 samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs create mode 100644 samples/Example.PluginApp/Plugins/HelloPlugin/HelloService.cs create mode 100644 samples/Example.PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj create mode 100644 samples/Example.PluginApp/Plugins/HelloPlugin/PluginStartup.cs create mode 100644 samples/Example.PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj create mode 100644 samples/Example.PluginApp/Plugins/UserPlugin/PluginStartup.cs create mode 100644 samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs create mode 100644 samples/Example.PluginApp/Plugins/UserPlugin/UserSqlService.cs create mode 100644 samples/Example.PluginApp/Plugins/UserPlugin/user.sql diff --git a/samples/Example.PluginApp/Contracts/IPluginStartup.cs b/samples/Example.PluginApp/Contracts/IPluginStartup.cs new file mode 100644 index 0000000..a6342f4 --- /dev/null +++ b/samples/Example.PluginApp/Contracts/IPluginStartup.cs @@ -0,0 +1,8 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace PluginApp.Contracts; + +public interface IPluginStartup +{ + void ConfigureServices(IServiceCollection services); +} diff --git a/samples/Example.PluginApp/Contracts/PluginApp.Contracts.csproj b/samples/Example.PluginApp/Contracts/PluginApp.Contracts.csproj new file mode 100644 index 0000000..78ea792 --- /dev/null +++ b/samples/Example.PluginApp/Contracts/PluginApp.Contracts.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + latest + + + + + + + diff --git a/samples/Example.PluginApp/Host/.env b/samples/Example.PluginApp/Host/.env new file mode 100644 index 0000000..b5bc156 --- /dev/null +++ b/samples/Example.PluginApp/Host/.env @@ -0,0 +1,5 @@ +PLUGINS=" + PluginApp.EmployeePlugin.dll + PluginApp.UserPlugin.dll + PluginApp.HelloPlugin.dll +" \ No newline at end of file diff --git a/samples/Example.PluginApp/Host/PluginApp.Host.csproj b/samples/Example.PluginApp/Host/PluginApp.Host.csproj new file mode 100644 index 0000000..3aeb68f --- /dev/null +++ b/samples/Example.PluginApp/Host/PluginApp.Host.csproj @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Example.PluginApp/Host/Program.cs b/samples/Example.PluginApp/Host/Program.cs new file mode 100644 index 0000000..d55c771 --- /dev/null +++ b/samples/Example.PluginApp/Host/Program.cs @@ -0,0 +1,62 @@ +using CPlugin.Net; +using DotEnv.Core; +using PluginApp.Contracts; +using System.Reflection; +using YeSql.Net; + +var builder = WebApplication.CreateBuilder(args); + +// Load .env file. +new EnvLoader().Load(); + +// Load plugins from the .env file. +var envConfiguration = new CPluginEnvConfiguration(); +PluginLoader.Load(envConfiguration); + +// Add services to the container. +var startups = TypeFinder.FindSubtypesOf(); +foreach (IPluginStartup startup in startups) + startup.ConfigureServices(builder.Services); + +// Adds the plugin assemblies as part of the application. +// Allows to register controllers of each plugin. +var mvcBuilder = builder.Services.AddControllers(); +foreach (Assembly assembly in PluginLoader.Assemblies) + mvcBuilder.AddApplicationPart(assembly); + +var sqlLoader = new YeSqlLoader(); +// Load SQL files from host application. +var sqlStatements = sqlLoader.Load(); + +// Load SQL files from plugins. +// Not all plugins need to have SQL files. +var directories = envConfiguration + .GetPluginFiles() + .Select(Path.GetDirectoryName) + .ToArray(); +sqlLoader.LoadFromDirectories(directories); + +builder.Services.AddSingleton(sqlStatements); + +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); + +public partial class Program { } diff --git a/samples/Example.PluginApp/Host/Properties/launchSettings.json b/samples/Example.PluginApp/Host/Properties/launchSettings.json new file mode 100644 index 0000000..e6ad6d9 --- /dev/null +++ b/samples/Example.PluginApp/Host/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:40859", + "sslPort": 44325 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5240", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7264;http://localhost:5240", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/samples/Example.PluginApp/Host/SqlController.cs b/samples/Example.PluginApp/Host/SqlController.cs new file mode 100644 index 0000000..2b22506 --- /dev/null +++ b/samples/Example.PluginApp/Host/SqlController.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc; +using YeSql.Net; + +namespace PluginApp.Host; + +[Route("api/[controller]")] +[ApiController] +public class SqlController : ControllerBase +{ + [HttpGet("OrderSql")] + public string GetOrdersSql(IYeSqlCollection sqlCollection) + => sqlCollection["GetOrders"]; +} diff --git a/samples/Example.PluginApp/Host/sample.sql b/samples/Example.PluginApp/Host/sample.sql new file mode 100644 index 0000000..574e03a --- /dev/null +++ b/samples/Example.PluginApp/Host/sample.sql @@ -0,0 +1,2 @@ +-- name: GetOrders +SELECT * FROM [order]; \ No newline at end of file diff --git a/samples/Example.PluginApp/Plugins/Directory.Build.props b/samples/Example.PluginApp/Plugins/Directory.Build.props new file mode 100644 index 0000000..e91cd56 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/Directory.Build.props @@ -0,0 +1,21 @@ + + + + + Debug + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'YeSql.Net.Examples.sln')) + $(ProjectRootDir)/Example.PluginApp/Host/bin/$(Configuration)/$(TargetFramework)/plugins/$(MSBuildProjectName) + true + + + + + false + runtime + + + + + + + diff --git a/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs b/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs new file mode 100644 index 0000000..21ac578 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace PluginApp.EmployeePlugin; + +[Route("api/[controller]")] +[ApiController] +public class EmployeeSqlController : ControllerBase +{ + [HttpGet] + public string GetCodeSql(EmployeeSqlService service) + => service.GetSqlCode(); +} diff --git a/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlService.cs b/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlService.cs new file mode 100644 index 0000000..db384dc --- /dev/null +++ b/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlService.cs @@ -0,0 +1,9 @@ +using YeSql.Net; + +namespace PluginApp.EmployeePlugin; + +public class EmployeeSqlService(IYeSqlCollection sqlCollection) +{ + public string GetSqlCode() + => sqlCollection["GetEmployees"]; +} diff --git a/samples/Example.PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj b/samples/Example.PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj new file mode 100644 index 0000000..9876443 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj @@ -0,0 +1,9 @@ + + + + Library + latest + true + + + diff --git a/samples/Example.PluginApp/Plugins/EmployeePlugin/PluginStartup.cs b/samples/Example.PluginApp/Plugins/EmployeePlugin/PluginStartup.cs new file mode 100644 index 0000000..38669f6 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/EmployeePlugin/PluginStartup.cs @@ -0,0 +1,15 @@ +using CPlugin.Net; +using PluginApp.Contracts; +using PluginApp.EmployeePlugin; + +[assembly: Plugin(typeof(PluginStartup))] + +namespace PluginApp.EmployeePlugin; + +public class PluginStartup : IPluginStartup +{ + public void ConfigureServices(IServiceCollection services) + { + services.AddTransient(); + } +} diff --git a/samples/Example.PluginApp/Plugins/EmployeePlugin/employee.sql b/samples/Example.PluginApp/Plugins/EmployeePlugin/employee.sql new file mode 100644 index 0000000..2df2ca0 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/EmployeePlugin/employee.sql @@ -0,0 +1,2 @@ +-- name: GetEmployees +SELECT * FROM [employee]; \ No newline at end of file diff --git a/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs b/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs new file mode 100644 index 0000000..c8afcaa --- /dev/null +++ b/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace PluginApp.HelloPlugin; + +[Route("api/[controller]")] +[ApiController] +public class HelloController : ControllerBase +{ + [HttpGet] + public string GetCodeSql(HelloService service) + => service.Greet(); +} diff --git a/samples/Example.PluginApp/Plugins/HelloPlugin/HelloService.cs b/samples/Example.PluginApp/Plugins/HelloPlugin/HelloService.cs new file mode 100644 index 0000000..5eaea9f --- /dev/null +++ b/samples/Example.PluginApp/Plugins/HelloPlugin/HelloService.cs @@ -0,0 +1,7 @@ +namespace PluginApp.HelloPlugin; + +public class HelloService +{ + public string Greet() + => "Hello World!"; +} diff --git a/samples/Example.PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj b/samples/Example.PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj new file mode 100644 index 0000000..9876443 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj @@ -0,0 +1,9 @@ + + + + Library + latest + true + + + diff --git a/samples/Example.PluginApp/Plugins/HelloPlugin/PluginStartup.cs b/samples/Example.PluginApp/Plugins/HelloPlugin/PluginStartup.cs new file mode 100644 index 0000000..bf7016d --- /dev/null +++ b/samples/Example.PluginApp/Plugins/HelloPlugin/PluginStartup.cs @@ -0,0 +1,15 @@ +using CPlugin.Net; +using PluginApp.Contracts; +using PluginApp.HelloPlugin; + +[assembly: Plugin(typeof(PluginStartup))] + +namespace PluginApp.HelloPlugin; + +public class PluginStartup : IPluginStartup +{ + public void ConfigureServices(IServiceCollection services) + { + services.AddTransient(); + } +} diff --git a/samples/Example.PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj b/samples/Example.PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj new file mode 100644 index 0000000..9876443 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj @@ -0,0 +1,9 @@ + + + + Library + latest + true + + + diff --git a/samples/Example.PluginApp/Plugins/UserPlugin/PluginStartup.cs b/samples/Example.PluginApp/Plugins/UserPlugin/PluginStartup.cs new file mode 100644 index 0000000..4b9d0de --- /dev/null +++ b/samples/Example.PluginApp/Plugins/UserPlugin/PluginStartup.cs @@ -0,0 +1,15 @@ +using CPlugin.Net; +using PluginApp.Contracts; +using PluginApp.UserPlugin; + +[assembly: Plugin(typeof(PluginStartup))] + +namespace PluginApp.UserPlugin; + +public class PluginStartup : IPluginStartup +{ + public void ConfigureServices(IServiceCollection services) + { + services.AddTransient(); + } +} diff --git a/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs b/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs new file mode 100644 index 0000000..0405ff7 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace PluginApp.UserPlugin; + +[Route("api/[controller]")] +[ApiController] +public class UserSqlController : ControllerBase +{ + [HttpGet] + public string GetCodeSql(UserSqlService service) + => service.GetSqlCode(); +} diff --git a/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlService.cs b/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlService.cs new file mode 100644 index 0000000..b90ba74 --- /dev/null +++ b/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlService.cs @@ -0,0 +1,9 @@ +using YeSql.Net; + +namespace PluginApp.UserPlugin; + +public class UserSqlService(IYeSqlCollection sqlCollection) +{ + public string GetSqlCode() + => sqlCollection["GetUsers"]; +} diff --git a/samples/Example.PluginApp/Plugins/UserPlugin/user.sql b/samples/Example.PluginApp/Plugins/UserPlugin/user.sql new file mode 100644 index 0000000..5adf1df --- /dev/null +++ b/samples/Example.PluginApp/Plugins/UserPlugin/user.sql @@ -0,0 +1,2 @@ +-- name: GetUsers +SELECT * FROM [user]; \ No newline at end of file diff --git a/samples/YeSql.Net.Examples.sln b/samples/YeSql.Net.Examples.sln index 3076feb..1aa4368 100644 --- a/samples/YeSql.Net.Examples.sln +++ b/samples/YeSql.Net.Examples.sln @@ -21,11 +21,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.NetFramework", "Exa EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.AspNetFramework", "Example.AspNetFramework\Example.AspNetFramework.csproj", "{968FCF41-955C-48F4-AB63-D39BAE47930F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.Contracts", "Example.PluginApp\Contracts\PluginApp.Contracts.csproj", "{711AEA1E-2C14-4E26-90F4-9CC21FC436E8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.Host", "Example.PluginApp\Host\PluginApp.Host.csproj", "{C4833FCA-491A-46E1-A9E5-EF34ABC469DF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.UserPlugin", "Example.PluginApp\Plugins\UserPlugin\PluginApp.UserPlugin.csproj", "{42398B01-238E-442E-B677-8563EF7957E2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.EmployeePlugin", "Example.PluginApp\Plugins\EmployeePlugin\PluginApp.EmployeePlugin.csproj", "{EDCC4759-3DBE-42C1-B520-68DC1C18DDCB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.HelloPlugin", "Example.PluginApp\Plugins\HelloPlugin\PluginApp.HelloPlugin.csproj", "{8A3E96F3-B6FE-4F0B-9421-49328822E36B}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{91D295C8-520D-46AF-95BC-D1E6C1E60534}" ProjectSection(SolutionItems) = preProject ..\props\build\CopySqlFilesToOutputDirectory.props = ..\props\build\CopySqlFilesToOutputDirectory.props ..\targets\build\CopySqlFilesToPublishDirectory.targets = ..\targets\build\CopySqlFilesToPublishDirectory.targets ..\Directory.Build.props = ..\Directory.Build.props + Example.PluginApp\Plugins\Directory.Build.props = Example.PluginApp\Plugins\Directory.Build.props ..\Directory.Packages.props = ..\Directory.Packages.props EndProjectSection EndProject @@ -71,6 +82,26 @@ Global {968FCF41-955C-48F4-AB63-D39BAE47930F}.Debug|Any CPU.Build.0 = Debug|Any CPU {968FCF41-955C-48F4-AB63-D39BAE47930F}.Release|Any CPU.ActiveCfg = Release|Any CPU {968FCF41-955C-48F4-AB63-D39BAE47930F}.Release|Any CPU.Build.0 = Release|Any CPU + {711AEA1E-2C14-4E26-90F4-9CC21FC436E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {711AEA1E-2C14-4E26-90F4-9CC21FC436E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {711AEA1E-2C14-4E26-90F4-9CC21FC436E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {711AEA1E-2C14-4E26-90F4-9CC21FC436E8}.Release|Any CPU.Build.0 = Release|Any CPU + {C4833FCA-491A-46E1-A9E5-EF34ABC469DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4833FCA-491A-46E1-A9E5-EF34ABC469DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4833FCA-491A-46E1-A9E5-EF34ABC469DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4833FCA-491A-46E1-A9E5-EF34ABC469DF}.Release|Any CPU.Build.0 = Release|Any CPU + {42398B01-238E-442E-B677-8563EF7957E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42398B01-238E-442E-B677-8563EF7957E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42398B01-238E-442E-B677-8563EF7957E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42398B01-238E-442E-B677-8563EF7957E2}.Release|Any CPU.Build.0 = Release|Any CPU + {EDCC4759-3DBE-42C1-B520-68DC1C18DDCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDCC4759-3DBE-42C1-B520-68DC1C18DDCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDCC4759-3DBE-42C1-B520-68DC1C18DDCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDCC4759-3DBE-42C1-B520-68DC1C18DDCB}.Release|Any CPU.Build.0 = Release|Any CPU + {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 2d13dcef9a9b6f491c3d416d32d873b347e48b81 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 12:59:38 -0500 Subject: [PATCH 03/12] refactor: Rename controller actions --- samples/Example.PluginApp/Host/SqlController.cs | 2 +- .../Plugins/EmployeePlugin/EmployeeSqlController.cs | 2 +- .../Example.PluginApp/Plugins/HelloPlugin/HelloController.cs | 2 +- .../Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/Example.PluginApp/Host/SqlController.cs b/samples/Example.PluginApp/Host/SqlController.cs index 2b22506..0c20c03 100644 --- a/samples/Example.PluginApp/Host/SqlController.cs +++ b/samples/Example.PluginApp/Host/SqlController.cs @@ -8,6 +8,6 @@ namespace PluginApp.Host; public class SqlController : ControllerBase { [HttpGet("OrderSql")] - public string GetOrdersSql(IYeSqlCollection sqlCollection) + public string GetOrderSql(IYeSqlCollection sqlCollection) => sqlCollection["GetOrders"]; } diff --git a/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs b/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs index 21ac578..4aa0a2e 100644 --- a/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs +++ b/samples/Example.PluginApp/Plugins/EmployeePlugin/EmployeeSqlController.cs @@ -7,6 +7,6 @@ namespace PluginApp.EmployeePlugin; public class EmployeeSqlController : ControllerBase { [HttpGet] - public string GetCodeSql(EmployeeSqlService service) + public string GetSqlCode(EmployeeSqlService service) => service.GetSqlCode(); } diff --git a/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs b/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs index c8afcaa..76d5be4 100644 --- a/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs +++ b/samples/Example.PluginApp/Plugins/HelloPlugin/HelloController.cs @@ -7,6 +7,6 @@ namespace PluginApp.HelloPlugin; public class HelloController : ControllerBase { [HttpGet] - public string GetCodeSql(HelloService service) + public string Greet(HelloService service) => service.Greet(); } diff --git a/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs b/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs index 0405ff7..3333017 100644 --- a/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs +++ b/samples/Example.PluginApp/Plugins/UserPlugin/UserSqlController.cs @@ -7,6 +7,6 @@ namespace PluginApp.UserPlugin; public class UserSqlController : ControllerBase { [HttpGet] - public string GetCodeSql(UserSqlService service) + public string GetSqlCode(UserSqlService service) => service.GetSqlCode(); } From fdf4c07981e59359ca20373163f1971bc5eb0d71 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 14:18:43 -0500 Subject: [PATCH 04/12] Overwrite env vars --- samples/Example.PluginApp/Host/Program.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/Example.PluginApp/Host/Program.cs b/samples/Example.PluginApp/Host/Program.cs index d55c771..4a392d7 100644 --- a/samples/Example.PluginApp/Host/Program.cs +++ b/samples/Example.PluginApp/Host/Program.cs @@ -7,7 +7,9 @@ var builder = WebApplication.CreateBuilder(args); // Load .env file. -new EnvLoader().Load(); +new EnvLoader() + .AllowOverwriteExistingVars() + .Load(); // Load plugins from the .env file. var envConfiguration = new CPluginEnvConfiguration(); From 447d0e36b9062cdc4caa0336bbd6b5dae143b732 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 14:20:05 -0500 Subject: [PATCH 05/12] test: Add tests for sample --- .../Example.PluginApp/Test/GlobalUsings.cs | 4 +++ .../Test/PluginApp.Host.Tests.csproj | 33 +++++++++++++++++++ samples/Example.PluginApp/Test/SqlTests.cs | 28 ++++++++++++++++ samples/YeSql.Net.Examples.sln | 6 ++++ 4 files changed, 71 insertions(+) create mode 100644 samples/Example.PluginApp/Test/GlobalUsings.cs create mode 100644 samples/Example.PluginApp/Test/PluginApp.Host.Tests.csproj create mode 100644 samples/Example.PluginApp/Test/SqlTests.cs diff --git a/samples/Example.PluginApp/Test/GlobalUsings.cs b/samples/Example.PluginApp/Test/GlobalUsings.cs new file mode 100644 index 0000000..db58734 --- /dev/null +++ b/samples/Example.PluginApp/Test/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using NUnit.Framework; +global using FluentAssertions; +global using Microsoft.AspNetCore.Mvc.Testing; +global using System.Net; \ No newline at end of file diff --git a/samples/Example.PluginApp/Test/PluginApp.Host.Tests.csproj b/samples/Example.PluginApp/Test/PluginApp.Host.Tests.csproj new file mode 100644 index 0000000..97008b6 --- /dev/null +++ b/samples/Example.PluginApp/Test/PluginApp.Host.Tests.csproj @@ -0,0 +1,33 @@ + + + + false + true + true + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Example.PluginApp/Test/SqlTests.cs b/samples/Example.PluginApp/Test/SqlTests.cs new file mode 100644 index 0000000..32cb5cb --- /dev/null +++ b/samples/Example.PluginApp/Test/SqlTests.cs @@ -0,0 +1,28 @@ +namespace PluginApp.Host.Tests; + +public class SqlTests +{ + [TestCase("/api/EmployeeSql", "SELECT * FROM [employee];")] + [TestCase("/api/UserSql", "SELECT * FROM [user];")] + [TestCase("/api/Sql/GetOrderSql", "SELECT * FROM [order];")] + [TestCase("/api/Hello", "Hello World!")] + public async Task Get_WhenSqlCodeIsRetrieved_ShouldReturnsHttpStatusCodeOk( + string requestUri, + string expectedResult) + { + // Arrange + using var factory = new WebApplicationFactory(); + var client = factory.CreateClient(); + + // Act + var httpResponse = await client.GetAsync(requestUri); + var result = (await httpResponse + .Content + .ReadAsStringAsync()) + .TrimEnd(Environment.NewLine.ToCharArray()); + + // Asserts + httpResponse.StatusCode.Should().Be(HttpStatusCode.OK); + result.Should().Be(expectedResult); + } +} diff --git a/samples/YeSql.Net.Examples.sln b/samples/YeSql.Net.Examples.sln index 1aa4368..30b9e8f 100644 --- a/samples/YeSql.Net.Examples.sln +++ b/samples/YeSql.Net.Examples.sln @@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.Contracts", "Exam EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.Host", "Example.PluginApp\Host\PluginApp.Host.csproj", "{C4833FCA-491A-46E1-A9E5-EF34ABC469DF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginApp.Host.Tests", "Example.PluginApp\Test\PluginApp.Host.Tests.csproj", "{BBD2189A-46B1-4CD6-BACA-904BCBA036BE}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.UserPlugin", "Example.PluginApp\Plugins\UserPlugin\PluginApp.UserPlugin.csproj", "{42398B01-238E-442E-B677-8563EF7957E2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginApp.EmployeePlugin", "Example.PluginApp\Plugins\EmployeePlugin\PluginApp.EmployeePlugin.csproj", "{EDCC4759-3DBE-42C1-B520-68DC1C18DDCB}" @@ -102,6 +104,10 @@ Global {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Release|Any CPU.ActiveCfg = Release|Any CPU {8A3E96F3-B6FE-4F0B-9421-49328822E36B}.Release|Any CPU.Build.0 = Release|Any CPU + {BBD2189A-46B1-4CD6-BACA-904BCBA036BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BBD2189A-46B1-4CD6-BACA-904BCBA036BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BBD2189A-46B1-4CD6-BACA-904BCBA036BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BBD2189A-46B1-4CD6-BACA-904BCBA036BE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 962130b160b32d835c34b4ec962cc2cc73d31e55 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 14:24:38 -0500 Subject: [PATCH 06/12] chore: Update dotnetcore.yml --- .github/workflows/dotnetcore.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 20de136..b01c756 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -24,4 +24,8 @@ jobs: - name: Test run: | dotnet test ./tests/YeSql.Net.Tests.csproj - dotnet test ./samples/Example.AspNetCore.Tests/Example.AspNetCore.Tests.csproj \ No newline at end of file + dotnet test ./samples/Example.AspNetCore.Tests/Example.AspNetCore.Tests.csproj + dotnet build ./samples/PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj + dotnet build ./samples/PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj + dotnet build ./samples/PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj + dotnet test ./samples/PluginApp/Test/PluginApp.Host.Tests.csproj \ No newline at end of file From a2050362a5f4b53cf7325cf2142b58aed45c5ac4 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Wed, 10 Jan 2024 14:26:57 -0500 Subject: [PATCH 07/12] fix: Add Example prefix --- .github/workflows/dotnetcore.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index b01c756..9eee002 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -25,7 +25,7 @@ jobs: run: | dotnet test ./tests/YeSql.Net.Tests.csproj dotnet test ./samples/Example.AspNetCore.Tests/Example.AspNetCore.Tests.csproj - dotnet build ./samples/PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj - dotnet build ./samples/PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj - dotnet build ./samples/PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj - dotnet test ./samples/PluginApp/Test/PluginApp.Host.Tests.csproj \ No newline at end of file + dotnet build ./samples/Example.PluginApp/Plugins/EmployeePlugin/PluginApp.EmployeePlugin.csproj + dotnet build ./samples/Example.PluginApp/Plugins/UserPlugin/PluginApp.UserPlugin.csproj + dotnet build ./samples/Example.PluginApp/Plugins/HelloPlugin/PluginApp.HelloPlugin.csproj + dotnet test ./samples/Example.PluginApp/Test/PluginApp.Host.Tests.csproj \ No newline at end of file From 648d5c06cb211abbc2bb68174af3dfdf09ca9633 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Thu, 11 Jan 2024 19:34:39 -0500 Subject: [PATCH 08/12] Remove configuration method --- samples/Example.PluginApp/Host/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/samples/Example.PluginApp/Host/Program.cs b/samples/Example.PluginApp/Host/Program.cs index 4a392d7..d55c771 100644 --- a/samples/Example.PluginApp/Host/Program.cs +++ b/samples/Example.PluginApp/Host/Program.cs @@ -7,9 +7,7 @@ var builder = WebApplication.CreateBuilder(args); // Load .env file. -new EnvLoader() - .AllowOverwriteExistingVars() - .Load(); +new EnvLoader().Load(); // Load plugins from the .env file. var envConfiguration = new CPluginEnvConfiguration(); From 8e98451bfea9231fd3a562c93cec5cd034789372 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Thu, 11 Jan 2024 19:35:28 -0500 Subject: [PATCH 09/12] test: Add a test case when no plugins are loaded --- samples/Example.PluginApp/Test/SqlTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/samples/Example.PluginApp/Test/SqlTests.cs b/samples/Example.PluginApp/Test/SqlTests.cs index 32cb5cb..02e900a 100644 --- a/samples/Example.PluginApp/Test/SqlTests.cs +++ b/samples/Example.PluginApp/Test/SqlTests.cs @@ -11,6 +11,7 @@ public async Task Get_WhenSqlCodeIsRetrieved_ShouldReturnsHttpStatusCodeOk( string expectedResult) { // Arrange + Environment.SetEnvironmentVariable("PLUGINS", ""); using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); @@ -25,4 +26,20 @@ public async Task Get_WhenSqlCodeIsRetrieved_ShouldReturnsHttpStatusCodeOk( httpResponse.StatusCode.Should().Be(HttpStatusCode.OK); result.Should().Be(expectedResult); } + + [Test] + public async Task Get_WhenNoPluginIsLoaded_ShouldNotThrowException() + { + // Arrange + Environment.SetEnvironmentVariable("PLUGINS", " "); + using var factory = new WebApplicationFactory(); + var client = factory.CreateClient(); + var requestUri = "/api/Hello"; + + // Act + var httpResponse = await client.GetAsync(requestUri); + + // Assert + httpResponse.StatusCode.Should().Be(HttpStatusCode.OK); + } } From e146f16ba9ce08dbfa4d7c1f7365ddb5c6c8abc0 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Thu, 11 Jan 2024 19:45:33 -0500 Subject: [PATCH 10/12] test: Change URI value --- samples/Example.PluginApp/Test/SqlTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Example.PluginApp/Test/SqlTests.cs b/samples/Example.PluginApp/Test/SqlTests.cs index 02e900a..cbdd19b 100644 --- a/samples/Example.PluginApp/Test/SqlTests.cs +++ b/samples/Example.PluginApp/Test/SqlTests.cs @@ -34,7 +34,7 @@ public async Task Get_WhenNoPluginIsLoaded_ShouldNotThrowException() Environment.SetEnvironmentVariable("PLUGINS", " "); using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); - var requestUri = "/api/Hello"; + var requestUri = "/api/Sql/GetOrderSql"; // Act var httpResponse = await client.GetAsync(requestUri); From 4e46b3e5cd66ce85281f34d2c4775d1e534b4cf0 Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Fri, 12 Jan 2024 12:22:16 -0500 Subject: [PATCH 11/12] fix route --- samples/Example.PluginApp/Test/SqlTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/Example.PluginApp/Test/SqlTests.cs b/samples/Example.PluginApp/Test/SqlTests.cs index cbdd19b..49c6c26 100644 --- a/samples/Example.PluginApp/Test/SqlTests.cs +++ b/samples/Example.PluginApp/Test/SqlTests.cs @@ -4,7 +4,7 @@ public class SqlTests { [TestCase("/api/EmployeeSql", "SELECT * FROM [employee];")] [TestCase("/api/UserSql", "SELECT * FROM [user];")] - [TestCase("/api/Sql/GetOrderSql", "SELECT * FROM [order];")] + [TestCase("/api/Sql/OrderSql", "SELECT * FROM [order];")] [TestCase("/api/Hello", "Hello World!")] public async Task Get_WhenSqlCodeIsRetrieved_ShouldReturnsHttpStatusCodeOk( string requestUri, @@ -34,7 +34,7 @@ public async Task Get_WhenNoPluginIsLoaded_ShouldNotThrowException() Environment.SetEnvironmentVariable("PLUGINS", " "); using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); - var requestUri = "/api/Sql/GetOrderSql"; + var requestUri = "/api/Sql/OrderSql"; // Act var httpResponse = await client.GetAsync(requestUri); From 61c93de8aee29bb06530b786140698f729de9eac Mon Sep 17 00:00:00 2001 From: MrDave1999 Date: Fri, 12 Jan 2024 12:29:30 -0500 Subject: [PATCH 12/12] test: Add the expected sql in a test --- samples/Example.PluginApp/Test/SqlTests.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/samples/Example.PluginApp/Test/SqlTests.cs b/samples/Example.PluginApp/Test/SqlTests.cs index 49c6c26..9af67ee 100644 --- a/samples/Example.PluginApp/Test/SqlTests.cs +++ b/samples/Example.PluginApp/Test/SqlTests.cs @@ -35,11 +35,17 @@ public async Task Get_WhenNoPluginIsLoaded_ShouldNotThrowException() using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); var requestUri = "/api/Sql/OrderSql"; + var expectedResult = "SELECT * FROM [order];"; // Act var httpResponse = await client.GetAsync(requestUri); + var result = (await httpResponse + .Content + .ReadAsStringAsync()) + .TrimEnd(Environment.NewLine.ToCharArray()); - // Assert + // Asserts httpResponse.StatusCode.Should().Be(HttpStatusCode.OK); + result.Should().Be(expectedResult); } }