2025-09-27 08:46:36 +03:30
|
|
|
using CMSMicroservice.Application.Common.Interfaces;
|
2025-12-02 03:30:36 +03:30
|
|
|
using CMSMicroservice.Application.DayaLoanCQ.Services;
|
2025-09-27 08:46:36 +03:30
|
|
|
using CMSMicroservice.Infrastructure.Persistence;
|
|
|
|
|
using CMSMicroservice.Infrastructure.Persistence.Interceptors;
|
2025-11-30 20:18:10 +03:30
|
|
|
using CMSMicroservice.Infrastructure.BackgroundJobs;
|
|
|
|
|
using CMSMicroservice.Infrastructure.Services.Monitoring;
|
2025-12-01 20:52:18 +03:30
|
|
|
using CMSMicroservice.Infrastructure.Configuration;
|
2025-12-02 03:30:36 +03:30
|
|
|
using CMSMicroservice.Infrastructure.Services.Payment;
|
2025-09-27 08:46:36 +03:30
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using System.Diagnostics;
|
2025-09-27 10:23:45 +03:30
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
using System.Text;
|
2025-09-27 23:59:05 +03:30
|
|
|
using CMSMicroservice.Infrastructure.Services;
|
2025-09-27 08:46:36 +03:30
|
|
|
|
|
|
|
|
namespace Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
|
|
|
|
|
public static class ConfigureServices
|
|
|
|
|
{
|
|
|
|
|
public static IServiceCollection AddInfrastructureServices(this IServiceCollection services, IConfiguration configuration)
|
|
|
|
|
{
|
2025-12-01 20:52:18 +03:30
|
|
|
// Configuration Settings
|
|
|
|
|
services.Configure<EmailSettings>(configuration.GetSection(EmailSettings.SectionName));
|
|
|
|
|
services.Configure<SmsSettings>(configuration.GetSection(SmsSettings.SectionName));
|
|
|
|
|
|
2025-09-27 08:46:36 +03:30
|
|
|
services.AddScoped<AuditableEntitySaveChangesInterceptor>();
|
|
|
|
|
services.AddScoped<ApplicationDbContextInitialiser>();
|
2025-09-27 23:59:05 +03:30
|
|
|
services.AddScoped<IGenerateJwtToken, GenerateJwtTokenService>();
|
2025-11-12 23:17:56 +03:30
|
|
|
services.AddScoped<IHashService, HashService>();
|
2025-11-30 20:18:10 +03:30
|
|
|
services.AddScoped<INetworkPlacementService, NetworkPlacementService>();
|
|
|
|
|
services.AddScoped<IAlertService, AlertService>();
|
|
|
|
|
services.AddScoped<IUserNotificationService, UserNotificationService>();
|
2025-12-02 03:30:36 +03:30
|
|
|
services.AddScoped<IDayaLoanApiService, MockDayaLoanApiService>(); // Mock - جایگزین با Real برای Production
|
|
|
|
|
|
|
|
|
|
// Payment Gateway Service - برای Development از Mock استفاده میشود
|
|
|
|
|
// برای Production یکی از سرویسهای واقعی را فعال کنید
|
|
|
|
|
var useRealPaymentGateway = configuration.GetValue<bool>("UseRealPaymentGateway", false);
|
|
|
|
|
|
|
|
|
|
if (useRealPaymentGateway)
|
|
|
|
|
{
|
|
|
|
|
var paymentProvider = configuration.GetValue<string>("PaymentProvider", "BankMellat");
|
|
|
|
|
|
|
|
|
|
if (paymentProvider == "Daya")
|
|
|
|
|
{
|
|
|
|
|
services.AddHttpClient<IPaymentGatewayService, DayaPaymentService>()
|
|
|
|
|
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
|
|
|
|
|
}
|
|
|
|
|
else if (paymentProvider == "BankMellat")
|
|
|
|
|
{
|
|
|
|
|
services.AddHttpClient<IPaymentGatewayService, BankMellatPaymentService>()
|
|
|
|
|
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException($"Invalid PaymentProvider: {paymentProvider}. Valid values: Daya, BankMellat");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Mock برای Development و Testing
|
|
|
|
|
services.AddScoped<IPaymentGatewayService, MockPaymentGatewayService>();
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-27 08:46:36 +03:30
|
|
|
services.AddScoped<IApplicationDbContext>(p => p.GetRequiredService<ApplicationDbContext>());
|
2025-11-30 20:18:10 +03:30
|
|
|
|
2025-12-01 20:52:18 +03:30
|
|
|
// Background Workers - Deprecated: Using Hangfire instead
|
|
|
|
|
// services.AddHostedService<WeeklyNetworkCommissionWorker>();
|
|
|
|
|
services.AddScoped<WeeklyCommissionJob>(); // Hangfire Job (Scoped for DI)
|
2025-11-30 20:18:10 +03:30
|
|
|
|
2025-09-27 08:46:36 +03:30
|
|
|
if (configuration.GetValue<bool>("UseInMemoryDatabase"))
|
|
|
|
|
{
|
|
|
|
|
services.AddDbContext<ApplicationDbContext>(options =>
|
|
|
|
|
options.UseInMemoryDatabase("MyMemoryDb"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
services.AddDbContext<ApplicationDbContext>(options =>
|
|
|
|
|
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
|
|
|
|
|
builder => builder.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));
|
|
|
|
|
}
|
|
|
|
|
#region AddAuthentication
|
|
|
|
|
|
|
|
|
|
var message = "";
|
|
|
|
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
|
|
|
.AddJwtBearer(jwtBearerOptions =>
|
|
|
|
|
{
|
2025-09-27 10:23:45 +03:30
|
|
|
//jwtBearerOptions.Authority = configuration["Authentication:Authority"];
|
|
|
|
|
//jwtBearerOptions.Audience = configuration["Authentication:Audience"];
|
|
|
|
|
//jwtBearerOptions.TokenValidationParameters.ValidateAudience = false;
|
|
|
|
|
//jwtBearerOptions.TokenValidationParameters.ValidateIssuer = true;
|
|
|
|
|
//jwtBearerOptions.TokenValidationParameters.ValidateIssuerSigningKey = false;
|
|
|
|
|
|
|
|
|
|
jwtBearerOptions.SaveToken = true;
|
|
|
|
|
jwtBearerOptions.RequireHttpsMetadata = false;
|
|
|
|
|
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
|
|
|
|
|
{
|
|
|
|
|
ValidateIssuer = true,
|
|
|
|
|
ValidateAudience = true,
|
|
|
|
|
ValidateLifetime = true,
|
|
|
|
|
ValidateIssuerSigningKey = true,
|
|
|
|
|
ValidIssuer = configuration["JwtIssuer"],
|
|
|
|
|
ValidAudience = configuration["JwtAudience"],
|
|
|
|
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtSecurityKey"]))
|
|
|
|
|
};
|
2025-09-27 08:46:36 +03:30
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
jwtBearerOptions.Events = new JwtBearerEvents
|
|
|
|
|
{
|
|
|
|
|
OnAuthenticationFailed = ctx =>
|
|
|
|
|
{
|
|
|
|
|
ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
|
|
|
message += "From OnAuthenticationFailed:\n";
|
|
|
|
|
message += ctx.Exception.Message;
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
OnChallenge = ctx =>
|
|
|
|
|
{
|
|
|
|
|
message += "From OnChallenge:\n";
|
|
|
|
|
ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
|
|
|
ctx.Response.ContentType = "text/plain";
|
|
|
|
|
return ctx.Response.WriteAsync(message);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
OnMessageReceived = ctx =>
|
|
|
|
|
{
|
|
|
|
|
message = "From OnMessageReceived:\n";
|
|
|
|
|
ctx.Request.Headers.TryGetValue("Authorization", out var BearerToken);
|
|
|
|
|
if (BearerToken.Count == 0)
|
|
|
|
|
BearerToken = "no Bearer token sent\n";
|
|
|
|
|
message += "Authorization Header sent: " + BearerToken + "\n";
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
OnTokenValidated = ctx =>
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("token: " + ctx.SecurityToken.ToString());
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(e);
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
services.AddAuthorization();
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2025-09-27 10:23:45 +03:30
|
|
|
|
2025-09-27 08:46:36 +03:30
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
}
|