diff --git a/PARR.DAL/PARR.DAL.csproj b/PARR.DAL/PARR.DAL.csproj
new file mode 100644
index 00000000..cfadb03d
--- /dev/null
+++ b/PARR.DAL/PARR.DAL.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/PARR_API/Contracts/V1/ApiRoutes.cs b/PARR_API/Contracts/V1/ApiRoutes.cs
new file mode 100644
index 00000000..17adcd4f
--- /dev/null
+++ b/PARR_API/Contracts/V1/ApiRoutes.cs
@@ -0,0 +1,42 @@
+namespace PARR_API.Contracts.V1
+{
+ // https://tproger.ru/translations/luchshie-praktiki-razrabotki-rest-api-20-sovetov/
+
+ //----------URL должен отражать структуру вложенных ресурсов----------
+ // GET /shops/2/products получить список продуктов из магазина 2.
+ // GET /shops/2/products/31 получить детали продукта 31 из магазина 2.
+ // DELETE /shops/2/products/31 удалить продукт 31 из магазина 2.
+ // PUT /shops/2/products/31 обновить данные о продукте 31. Используйте PUT на URL ресурса, а не коллекции.
+ // POST /shops создать новый магазин и вернуть данные о нём.Используйте POST на URL коллекции.
+
+ //---------URL должен начинаться с коллекции и заканчиваться идентификатором---------
+ // GET /shops/:shopId/ или GET /category/:categoryId
+
+ public static class ApiRoutes
+ {
+ public const string Root = "api";
+
+ public const string Version = "v1";
+
+ public const string Base = Root + "/" + Version;
+
+ public static class ApiStatus
+ {
+ public const string Version = Base + "/version";
+ public const string Health = Base + "/health";
+ public const string Metrics = Base + "/metrics";
+ }
+
+ //public static class Layer
+ //{
+ // public const string GetAll = Base + "/layers/";
+ // public const string Get = Base + "/layers/" + getParam;
+
+ // public const string GetAreas = Base + "/layers/" + getParam + "/areas";
+ // public const string GetPlaces = Base + "/layers/" + getParam + "/places";
+ // public const string GetTemplates = Base + "/layers/" + getParam + "/templates";
+
+ // public const string getParam = "{id}";
+ //}
+ }
+}
diff --git a/PARR_API/Controllers/V1/ApiStatusController.cs b/PARR_API/Controllers/V1/ApiStatusController.cs
new file mode 100644
index 00000000..b9b9d8ea
--- /dev/null
+++ b/PARR_API/Controllers/V1/ApiStatusController.cs
@@ -0,0 +1,9 @@
+using PARR_API.Controllers.V1.Base;
+
+namespace PARR_API.Controllers.V1
+{
+ public class ApiStatusController : BaseApiController
+ {
+ //TODO:
+ }
+}
diff --git a/PARR_API/Controllers/V1/Base/BaseApiController.cs b/PARR_API/Controllers/V1/Base/BaseApiController.cs
new file mode 100644
index 00000000..aa33350a
--- /dev/null
+++ b/PARR_API/Controllers/V1/Base/BaseApiController.cs
@@ -0,0 +1,10 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace PARR_API.Controllers.V1.Base
+{
+ [ApiController]
+ public class BaseApiController : ControllerBase
+ {
+
+ }
+}
diff --git a/PARR_API/Controllers/WeatherForecastController.cs b/PARR_API/Controllers/WeatherForecastController.cs
deleted file mode 100644
index 087f6681..00000000
--- a/PARR_API/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace PARR_API.Controllers
-{
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private static readonly string[] Summaries = new[]
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
- private readonly ILogger _logger;
-
- public WeatherForecastController(ILogger logger)
- {
- _logger = logger;
- }
-
- [HttpGet(Name = "GetWeatherForecast")]
- public IEnumerable Get()
- {
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = Summaries[Random.Shared.Next(Summaries.Length)]
- })
- .ToArray();
- }
- }
-}
\ No newline at end of file
diff --git a/PARR_API/Installers/ApiServicesInstaller.cs b/PARR_API/Installers/ApiServicesInstaller.cs
new file mode 100644
index 00000000..32078df9
--- /dev/null
+++ b/PARR_API/Installers/ApiServicesInstaller.cs
@@ -0,0 +1,28 @@
+using PARR_API.Services.Implementations;
+using PARR_API.Services.Interfaces;
+
+namespace PARR_API.Installers
+{
+ ///
+ /// Самописные сервисы которые используются для АПИ
+ ///
+ public static class ApiServicesInstaller
+ {
+ public static void InstallApiServices(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddSingleton(provider =>
+ {
+ var accessor = provider.GetRequiredService();
+ var request = accessor.HttpContext.Request;
+ var absoluteUri = string.Concat(request.Scheme, "://", request.Host.ToUriComponent(), "/");
+
+ return new UriService(absoluteUri);
+ });
+
+
+ //services.AddTransient();
+
+
+ }
+ }
+}
diff --git a/PARR_API/Installers/CorsInstaller.cs b/PARR_API/Installers/CorsInstaller.cs
new file mode 100644
index 00000000..b760c21b
--- /dev/null
+++ b/PARR_API/Installers/CorsInstaller.cs
@@ -0,0 +1,25 @@
+using PARR_API.Settings;
+
+namespace PARR_API.Installers
+{
+ public static class CorsInstaller
+ {
+ public static void InstallCorsServices(this IServiceCollection services)
+ {
+ services.AddCors();
+ }
+
+ public static void InstallCors(this WebApplication app, WebApplicationBuilder builder)
+ {
+ var corsSettings = new CorsSettings();
+ builder.Configuration.GetSection(nameof(CorsSettings)).Bind(corsSettings);
+
+ app.UseCors(opt =>
+ opt.WithOrigins(corsSettings.AllowHostsArray)
+ .AllowAnyHeader()
+ .AllowAnyMethod()
+ );
+ }
+
+ }
+}
diff --git a/PARR_API/Installers/SettingsInstaller.cs b/PARR_API/Installers/SettingsInstaller.cs
new file mode 100644
index 00000000..46c5420d
--- /dev/null
+++ b/PARR_API/Installers/SettingsInstaller.cs
@@ -0,0 +1,17 @@
+namespace PARR_API.Installers
+{
+ ///
+ /// Биндинги из конфига appsettings
+ ///
+ public static class SettingsInstaller
+ {
+ public static void InstallSettings(this IServiceCollection services, IConfiguration configuration)
+ {
+ //var storageSettings = new StorageSettings();
+ //configuration.GetSection(nameof(StorageSettings)).Bind(storageSettings);
+ //services.AddSingleton(storageSettings);
+
+ //TODO: add other
+ }
+ }
+}
diff --git a/PARR_API/Installers/SwaggerInstaller.cs b/PARR_API/Installers/SwaggerInstaller.cs
new file mode 100644
index 00000000..a53be633
--- /dev/null
+++ b/PARR_API/Installers/SwaggerInstaller.cs
@@ -0,0 +1,47 @@
+using Microsoft.OpenApi.Models;
+using System.Reflection;
+
+namespace PARR_API.Installers
+{
+ public static class SwaggerInstaller
+ {
+ public static void InstallSwaggerService(this IServiceCollection services, IConfiguration configuration)
+ {
+ // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+ services.AddEndpointsApiExplorer();
+
+ var version = Assembly.GetEntryAssembly()?.GetCustomAttribute()?.InformationalVersion ?? "1.0.0";
+
+ services.AddSwaggerGen(x =>
+ {
+ //TODO:
+ x.SwaggerDoc(
+ "v1",
+ new OpenApiInfo
+ {
+ Title = "GEO API",
+ Version = $"v{version}",
+ Description = "API for the project \"GEO DVGD\"",
+ Contact = new OpenApiContact { Email = "IVC_TrubnikovME@dvgd.rzd;IVC_KuznetsovMV@dvgd.rzd", Name = "Trubnikov M.E., Kuznetsov M.V." },
+ License = new OpenApiLicense { Name = "© PTK-DVGD Software LLC" }
+ });
+
+ // Set the comments path for the Swagger JSON and UI.
+ var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
+ var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
+ x.IncludeXmlComments(xmlPath);
+ });
+ }
+
+
+ public static void InstallSwagger(this WebApplication app)
+ {
+ // Configure the HTTP request pipeline.
+ if (app.Environment.IsDevelopment())
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI();
+ }
+ }
+ }
+}
diff --git a/PARR_API/MappingProfiles/DomainToResponseProfile.cs b/PARR_API/MappingProfiles/DomainToResponseProfile.cs
new file mode 100644
index 00000000..ec5db6c0
--- /dev/null
+++ b/PARR_API/MappingProfiles/DomainToResponseProfile.cs
@@ -0,0 +1,12 @@
+using AutoMapper;
+
+namespace PARR_API.MappingProfiles
+{
+ public class DomainToResponseProfile : Profile
+ {
+ public DomainToResponseProfile()
+ {
+ // из проекта наружу
+ }
+ }
+}
diff --git a/PARR_API/MappingProfiles/RequestToDomainProfile.cs b/PARR_API/MappingProfiles/RequestToDomainProfile.cs
new file mode 100644
index 00000000..6c9fae67
--- /dev/null
+++ b/PARR_API/MappingProfiles/RequestToDomainProfile.cs
@@ -0,0 +1,12 @@
+using AutoMapper;
+
+namespace PARR_API.MappingProfiles
+{
+ public class RequestToDomainProfile : Profile
+ {
+ public RequestToDomainProfile()
+ {
+ // снаружи в проект
+ }
+ }
+}
diff --git a/PARR_API/PARR_API.csproj b/PARR_API/PARR_API.csproj
index 0dd093e9..3616e162 100644
--- a/PARR_API/PARR_API.csproj
+++ b/PARR_API/PARR_API.csproj
@@ -4,11 +4,33 @@
net7.0
enable
enable
+ True
+
+
+
+ 1701;1702;1591;1587;1573;NU1803
+
+
+
+ 1701;1702;1591;1587;1573;NU1803
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PARR_API/Program.cs b/PARR_API/Program.cs
index df2434ce..54062b05 100644
--- a/PARR_API/Program.cs
+++ b/PARR_API/Program.cs
@@ -1,20 +1,36 @@
+using FluentValidation;
+using PARR_API.Installers;
+using Serilog;
+using System.Reflection;
+
var builder = WebApplication.CreateBuilder(args);
+builder.Host.UseSerilog((context, config) =>
+{
+ config
+ .WriteTo.Console()
+ .ReadFrom.Configuration(builder.Configuration);
+});
+
// Add services to the container.
+builder.Services.InstallApiServices(builder.Configuration);
+builder.Services.InstallSettings(builder.Configuration);
+builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
+
+builder.Services.AddHttpContextAccessor();
builder.Services.AddControllers();
-// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
+
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
+builder.Services.InstallSwaggerService(builder.Configuration);
+
var app = builder.Build();
// Configure the HTTP request pipeline.
-if (app.Environment.IsDevelopment())
-{
- app.UseSwagger();
- app.UseSwaggerUI();
-}
+app.InstallSwagger();
app.UseAuthorization();
diff --git a/PARR_API/Services/Implementations/UriService.cs b/PARR_API/Services/Implementations/UriService.cs
new file mode 100644
index 00000000..c42c35e7
--- /dev/null
+++ b/PARR_API/Services/Implementations/UriService.cs
@@ -0,0 +1,35 @@
+using PARR_API.Services.Interfaces;
+
+namespace PARR_API.Services.Implementations
+{
+ public class UriService : IUriService
+ {
+ private readonly string baseUri;
+
+ public UriService(string baseUri)
+ {
+ this.baseUri = baseUri;
+ }
+
+ public Uri GetAllUri(string apiRoutesGetAll)
+ {
+ return new Uri(baseUri + apiRoutesGetAll);
+ }
+
+ public Uri GetUri(string apiRoutesGet, string apiRoutesGetParam, string value)
+ {
+ var modifiedUri = apiRoutesGet.Replace(apiRoutesGetParam, value);
+ return new Uri(baseUri + modifiedUri);
+ }
+
+ public Uri GetUri(string apiRoutesGet, string apiRoutesGetParam, Guid value)
+ {
+ return GetUri(apiRoutesGet, apiRoutesGetParam, value.ToString());
+ }
+
+ public Uri GetBaseUri()
+ {
+ return new Uri(baseUri);
+ }
+ }
+}
diff --git a/PARR_API/Services/Interfaces/IUriService.cs b/PARR_API/Services/Interfaces/IUriService.cs
new file mode 100644
index 00000000..79aa67e0
--- /dev/null
+++ b/PARR_API/Services/Interfaces/IUriService.cs
@@ -0,0 +1,10 @@
+namespace PARR_API.Services.Interfaces
+{
+ public interface IUriService
+ {
+ Uri GetBaseUri();
+ Uri GetUri(string apiRoutesGet, string apiRoutesGetParam, string value);
+ Uri GetUri(string apiRoutesGet, string apiRoutesGetParam, Guid value);
+ Uri GetAllUri(string apiRoutesGetAll);
+ }
+}
diff --git a/PARR_API/Settings/CorsSettings.cs b/PARR_API/Settings/CorsSettings.cs
new file mode 100644
index 00000000..165882b5
--- /dev/null
+++ b/PARR_API/Settings/CorsSettings.cs
@@ -0,0 +1,9 @@
+namespace PARR_API.Settings
+{
+ public class CorsSettings
+ {
+ public string AllowedHosts { get; set; } = string.Empty;
+
+ public string[] AllowHostsArray => AllowedHosts.Split(';').Select(t => t.Trim()).ToArray();
+ }
+}
diff --git a/PARR_API/WeatherForecast.cs b/PARR_API/WeatherForecast.cs
deleted file mode 100644
index 1a6557ed..00000000
--- a/PARR_API/WeatherForecast.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace PARR_API
-{
- public class WeatherForecast
- {
- public DateOnly Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
- public string? Summary { get; set; }
- }
-}
\ No newline at end of file
diff --git a/PARR_API/appsettings.json b/PARR_API/appsettings.json
index 10f68b8c..2c17a37e 100644
--- a/PARR_API/appsettings.json
+++ b/PARR_API/appsettings.json
@@ -1,9 +1,33 @@
{
+ "ConnectionStrings": {
+ "DefaultConnection": "Server=10.99.253.184;Database=geo;User Id=app_geo; Password=Khdlifg(G875904HJFfd@3;"
+ },
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
- "AllowedHosts": "*"
+ "Serilog": {
+ "MinimumLevel": {
+ "Default": "Information",
+ "Override": {
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "WriteTo": [
+ {
+ "Name": "File",
+ "Args": {
+ "path": "log/log-.txt",
+ "rollingInterval": "Day"
+ }
+ }
+ ]
+ },
+ "AllowedHosts": "*",
+ "CorsSettings": {
+ "AllowedHosts": "*"
+ }
}