Refactor services and configuration handling for improved clarity and performance
This commit is contained in:
parent
4bb348cb7f
commit
d18b736e36
8
Pipefy.code-workspace
Normal file
8
Pipefy.code-workspace
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class Program
|
|||||||
var serviceCollection = new ServiceCollection();
|
var serviceCollection = new ServiceCollection();
|
||||||
serviceCollection.AddSingleton<IConfigurationService, ConfigurationService>();
|
serviceCollection.AddSingleton<IConfigurationService, ConfigurationService>();
|
||||||
serviceCollection.AddSingleton<IPipefyApiService>(provider => {
|
serviceCollection.AddSingleton<IPipefyApiService>(provider => {
|
||||||
var config = provider.GetRequiredService<IConfigurationService>().LoadAppSettings();
|
var config = provider.GetRequiredService<IConfigurationService>().GetAppSettings();
|
||||||
return new PipefyApiService(config.PIPEFY_API_URL, config.PIPEFY_API_TOKEN);
|
return new PipefyApiService(config.PIPEFY_API_URL, config.PIPEFY_API_TOKEN);
|
||||||
});
|
});
|
||||||
serviceCollection.AddSingleton<IDatabaseService, DatabaseService>();
|
serviceCollection.AddSingleton<IDatabaseService, DatabaseService>();
|
||||||
@ -31,7 +31,7 @@ class Program
|
|||||||
var serviceProvider = serviceCollection.BuildServiceProvider();
|
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||||
|
|
||||||
var configService = serviceProvider.GetRequiredService<IConfigurationService>();
|
var configService = serviceProvider.GetRequiredService<IConfigurationService>();
|
||||||
var AppSettings = configService.LoadAppSettings();
|
var AppSettings = configService.GetAppSettings();
|
||||||
if (AppSettings is null){ Environment.Exit(1); }
|
if (AppSettings is null){ Environment.Exit(1); }
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
|
|
||||||
@ -53,6 +53,7 @@ class Program
|
|||||||
List<ClasseEmpresas> databaseData = databaseService.GetDataFromDatabase(AppSettings.DB_PATH);
|
List<ClasseEmpresas> databaseData = databaseService.GetDataFromDatabase(AppSettings.DB_PATH);
|
||||||
var businessLogic = serviceProvider.GetRequiredService<IBusinessLogicService>();
|
var businessLogic = serviceProvider.GetRequiredService<IBusinessLogicService>();
|
||||||
List<ClasseEmpresas> recordsMissingInJson = businessLogic.CompareData(databaseData, jsonList, jsonListGestores);
|
List<ClasseEmpresas> recordsMissingInJson = businessLogic.CompareData(databaseData, jsonList, jsonListGestores);
|
||||||
|
recordsMissingInJson.AddRange(businessLogic.CompareData(jsonList, databaseData, jsonListGestores));
|
||||||
if (recordsMissingInJson.Count != 0 && recordsMissingInJson != null)
|
if (recordsMissingInJson.Count != 0 && recordsMissingInJson != null)
|
||||||
{
|
{
|
||||||
await pipefyApi.CreateRecordsAsync(AppSettings.PIPEFY_TABLE_ID, recordsMissingInJson);
|
await pipefyApi.CreateRecordsAsync(AppSettings.PIPEFY_TABLE_ID, recordsMissingInJson);
|
||||||
@ -62,7 +63,7 @@ class Program
|
|||||||
int maxCGestao = recordsMissingInJson.OrderByDescending(s => s.gestores!.Length).First().gestores!.Length;
|
int maxCGestao = recordsMissingInJson.OrderByDescending(s => s.gestores!.Length).First().gestores!.Length;
|
||||||
foreach (var record in recordsMissingInJson)
|
foreach (var record in recordsMissingInJson)
|
||||||
{
|
{
|
||||||
Console.WriteLine(String.Format($"| ID: {{0,{maxCId}}} | Nome: {{1,{maxCNome}}} | Modalidade: {{2,{maxCMod}}} | Gestão: {{3,{maxCGestao}}} |",record.c_digo_smart,record.nome_da_empresa,record.modalidade,record.gestores));
|
Console.WriteLine(String.Format($"| ID: {{0,{maxCId}}} | Nome: {{1,{maxCNome}}} | Modalidade: {{2,{maxCMod}}} | Gestão: {{3,{maxCGestao}}} |", record.c_digo_smart, record.nome_da_empresa, record.modalidade, record.gestores));
|
||||||
}
|
}
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ This document outlines a step-by-step plan to refactor the Pipefy project to com
|
|||||||
- `Models/`: For data models (move from `data.cs`).
|
- `Models/`: For data models (move from `data.cs`).
|
||||||
- `Mappers/`: For mapping logic between API/DB and domain models (optional, if mapping grows).
|
- `Mappers/`: For mapping logic between API/DB and domain models (optional, if mapping grows).
|
||||||
- [ ] Integrate ORM (e.g., Entity Framework Core) to abstract DB access and ease future DB changes. (Next step)
|
- [ ] Integrate ORM (e.g., Entity Framework Core) to abstract DB access and ease future DB changes. (Next step)
|
||||||
|
- Note: Current structure is well-separated; ORM will further improve OCP and testability.
|
||||||
- [x] Move or create files as needed for separation of concerns.
|
- [x] Move or create files as needed for separation of concerns.
|
||||||
|
|
||||||
## 3. Single Responsibility Principle (SRP)
|
## 3. Single Responsibility Principle (SRP)
|
||||||
@ -29,17 +30,21 @@ This document outlines a step-by-step plan to refactor the Pipefy project to com
|
|||||||
- [x] Extract data mapping logic into `IDataMapper` and `DataMapper`.
|
- [x] Extract data mapping logic into `IDataMapper` and `DataMapper`.
|
||||||
- [x] Extract business logic (comparison, orchestration) into `IBusinessLogicService` and `BusinessLogicService`.
|
- [x] Extract business logic (comparison, orchestration) into `IBusinessLogicService` and `BusinessLogicService`.
|
||||||
- [x] Remove static business/data methods from `Program.cs` and ensure all logic is in services.
|
- [x] Remove static business/data methods from `Program.cs` and ensure all logic is in services.
|
||||||
|
- Note: All main responsibilities are separated. Consider splitting services further if logic grows (e.g., separate API read/write, config providers).
|
||||||
|
|
||||||
## 4. Open/Closed Principle (OCP)
|
## 4. Open/Closed Principle (OCP)
|
||||||
- [x] Define interfaces for each service (already done: IConfigurationService, IPipefyApiService, IDatabaseService, IDataMapper, IBusinessLogicService).
|
- [x] Define interfaces for each service (already done: IConfigurationService, IPipefyApiService, IDatabaseService, IDataMapper, IBusinessLogicService).
|
||||||
- [x] Ensure new data sources or logic can be added by implementing new classes, not modifying existing ones (all main logic is now behind interfaces and DI).
|
- [x] Ensure new data sources or logic can be added by implementing new classes, not modifying existing ones (all main logic is now behind interfaces and DI).
|
||||||
|
- Note: Future data sources or logic can be added via new classes.
|
||||||
|
|
||||||
## 5. Liskov Substitution Principle (LSP)
|
## 5. Liskov Substitution Principle (LSP)
|
||||||
- [ ] Ensure all service implementations can be replaced by their interfaces without breaking functionality.
|
- [ ] Ensure all service implementations can be replaced by their interfaces without breaking functionality.
|
||||||
|
- Note: Add/expand unit tests to verify all service implementations can be swapped without breaking consumers. Ensure interfaces do not expose implementation-specific details.
|
||||||
|
|
||||||
## 6. Interface Segregation Principle (ISP)
|
## 6. Interface Segregation Principle (ISP)
|
||||||
- [ ] Keep interfaces focused and small.
|
- [ ] Keep interfaces focused and small.
|
||||||
- [ ] Split large interfaces if needed.
|
- [ ] Split large interfaces if needed.
|
||||||
|
- Note: Review interfaces for granularity. Split any that grow too large or have unrelated methods.
|
||||||
|
|
||||||
## 7. Dependency Inversion Principle (DIP)
|
## 7. Dependency Inversion Principle (DIP)
|
||||||
- [x] Refactor `Program.cs` to depend on abstractions (interfaces), not concrete classes.
|
- [x] Refactor `Program.cs` to depend on abstractions (interfaces), not concrete classes.
|
||||||
@ -48,10 +53,12 @@ This document outlines a step-by-step plan to refactor the Pipefy project to com
|
|||||||
## 8. Testing
|
## 8. Testing
|
||||||
- [ ] Add or update unit tests for each service.
|
- [ ] Add or update unit tests for each service.
|
||||||
- [ ] Ensure business logic is testable in isolation.
|
- [ ] Ensure business logic is testable in isolation.
|
||||||
|
- Note: Prioritize unit tests for business logic and service interfaces. Use mocks/fakes to test substitutability and isolation.
|
||||||
|
|
||||||
## 9. Documentation
|
## 9. Documentation
|
||||||
- [ ] Update this plan as you progress.
|
- [ ] Update this plan as you progress.
|
||||||
- [ ] Document new structure and usage in a `README.md` or similar file.
|
- [ ] Document new structure and usage in a `README.md` or similar file.
|
||||||
|
- Note: Document service responsibilities and interface contracts. Add XML comments to public APIs.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -61,4 +68,4 @@ This document outlines a step-by-step plan to refactor the Pipefy project to com
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_Last updated: May 16, 2025_
|
_Last updated: May 19, 2025_
|
||||||
|
|||||||
@ -17,14 +17,5 @@ namespace Pipefy.Services
|
|||||||
{
|
{
|
||||||
return _configuration.GetSection("AppSettings").Get<AppSettings>()!;
|
return _configuration.GetSection("AppSettings").Get<AppSettings>()!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppSettings LoadAppSettings()
|
|
||||||
{
|
|
||||||
var configurationBuilder = new ConfigurationBuilder()
|
|
||||||
.SetBasePath(Directory.GetCurrentDirectory())
|
|
||||||
.AddJsonFile("appsettings.json", optional: false);
|
|
||||||
IConfiguration configuration = configurationBuilder.Build();
|
|
||||||
return configuration.GetSection("AppSettings").Get<AppSettings>()!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.OleDb;
|
using System.Data.OleDb;
|
||||||
using System.Text;
|
using Dapper;
|
||||||
using Pipefy.Models;
|
using Pipefy.Models;
|
||||||
|
|
||||||
namespace Pipefy.Services
|
namespace Pipefy.Services
|
||||||
@ -10,38 +10,24 @@ namespace Pipefy.Services
|
|||||||
public List<ClasseEmpresas> GetDataFromDatabase(string connSourcePath)
|
public List<ClasseEmpresas> GetDataFromDatabase(string connSourcePath)
|
||||||
{
|
{
|
||||||
string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + connSourcePath + ";Jet OLEDB:Database Password=gds21;";
|
string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + connSourcePath + ";Jet OLEDB:Database Password=gds21;";
|
||||||
List<ClasseEmpresas> data = new List<ClasseEmpresas>();
|
|
||||||
using (OleDbConnection connection = new OleDbConnection(connectionString))
|
using (OleDbConnection connection = new OleDbConnection(connectionString))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
StringBuilder sqlQuery = new StringBuilder();
|
string sqlQuery = @"SELECT cod_smart_cliente AS c_digo_smart,
|
||||||
sqlQuery.Append("SELECT cod_smart_cliente, \n");
|
cliente AS nome_da_empresa,
|
||||||
sqlQuery.Append(" cliente, \n");
|
modalidade,
|
||||||
sqlQuery.Append(" modalidade, \n");
|
gestao AS gestores
|
||||||
sqlQuery.Append(" gestao \n");
|
FROM dados_cadastrais
|
||||||
sqlQuery.Append("FROM dados_cadastrais \n");
|
WHERE cod_smart_unidade LIKE '%001'
|
||||||
sqlQuery.Append("WHERE cod_smart_unidade LIKE \"%001\" \n");
|
AND unidade_gerenciada;";
|
||||||
sqlQuery.Append(" AND unidade_gerenciada;");
|
var data = connection.Query<ClasseEmpresas>(sqlQuery).AsList();
|
||||||
using (OleDbCommand command = new OleDbCommand(sqlQuery.ToString(), connection))
|
// rec_id is not in the DB, set to empty string
|
||||||
|
foreach (var item in data)
|
||||||
{
|
{
|
||||||
using (OleDbDataReader reader = command.ExecuteReader())
|
item.rec_id = string.Empty;
|
||||||
{
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
ClasseEmpresas record = new ClasseEmpresas
|
|
||||||
{
|
|
||||||
c_digo_smart = reader["Cod_Smart_cliente"].ToString(),
|
|
||||||
nome_da_empresa = reader["Cliente"].ToString(),
|
|
||||||
modalidade = reader["Modalidade"].ToString(),
|
|
||||||
gestores = reader["Gestao"].ToString(),
|
|
||||||
rec_id = ""
|
|
||||||
};
|
|
||||||
data.Add(record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,5 @@ namespace Pipefy.Services
|
|||||||
public interface IConfigurationService
|
public interface IConfigurationService
|
||||||
{
|
{
|
||||||
AppSettings GetAppSettings();
|
AppSettings GetAppSettings();
|
||||||
AppSettings LoadAppSettings();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user