Remark : DB 쉽게 세팅, ICacheGetSet 으로 간단하게 구성 하기
- using InMemoryCacheCore.App_Data.MsSQL 또는 .MySQL 선택
- V11, V12, V13 버전관리 하기
UML
Files
MsSQL -> AirlineDBContext.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using Microsoft.EntityFrameworkCore; using InMemoryCacheCore.Models; namespace InMemoryCacheCore.App_Data.MsSQL { public class AirlineDBContext : DbContext { static readonly string MySQLconnectionString = "Server=SQLOLEDB.1;Password=XXXXXX;Persist Security Info=True;User ID=IDXXX;Initial Catalog=BasicCode;Data Source=XXX.XXX.XXX.XXX"; public DbSet<Code>? AIRLINE { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(MySQLconnectionString); } } } |
MySQL -> AirlineDBContext.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using Microsoft.EntityFrameworkCore; using InMemoryCacheCore.Models; namespace InMemoryCacheCore.App_Data.MySQL { public class AirlineDBContext : DbContext { static readonly string connectionString = "Server=XXX.XXX.XXX.XXX,3306;User ID=XXXX;Password=XXXXX;Database=BasicCode"; public DbSet<Code>? AIRLINE { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); } } } |
AirlineController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using InMemoryCacheCore.Services02.V13; using Microsoft.AspNetCore.Mvc; namespace InMemoryCacheCore.Controllers { [Route("api/[controller]")] [ApiController] public class AirlineController : ControllerBase { private readonly ICacheGetSet _cacheGetSet; private readonly string _cacheKey = "_ACode"; public AirlineController(ICacheGetSet cacheGetSet ) { _cacheGetSet = cacheGetSet ?? throw new ArgumentNullException(nameof(cacheGetSet)); } // GET: api/<ValuesController> [HttpGet] public async Task<IEnumerable<Code>> Get() { try { IEnumerable<Code>? codes = await _cacheGetSet.CacheGet(_cacheKey); return codes; } catch { return Enumerable.Empty<Code>(); } } } } |
AirlineHttpClient.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using Microsoft.EntityFrameworkCore; using InMemoryCacheCore.Models; using InMemoryCacheCore.App_Data.MySQL; namespace InMemoryCacheCore.Infrastructure { public interface IHttpClient { Task<IEnumerable<Code>> Get(); } public class AirlineHttpClient : IHttpClient { public async Task<IEnumerable<Code>> Get() { AirlineDBContext _context = new(); if (_context.AIRLINE != null) { var codesResponse = await _context.AIRLINE.ToListAsync(); return codesResponse; } else { //throw new Exception(""); return Array.Empty<Code>(); } } } } |
CacheProvider.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
using Microsoft.Extensions.Caching.Memory; namespace InMemoryCacheCore.Infrastructure { public interface ICacheProvider { T? GetFromCache<T>(string key) where T : class; void SetCache<T>(string key, T value, MemoryCacheEntryOptions options) where T : class; void ClearCache(string key); } public class CacheProvider : ICacheProvider { private readonly IMemoryCache _cache; public CacheProvider(IMemoryCache cache) { _cache = cache; } public T? GetFromCache<T>(string key) where T : class { //_cache.TryGetValue(key, out T cachedResponse); //return cachedResponse as T; return _cache.Get<T>(key); } public void SetCache<T>(string key, T value, MemoryCacheEntryOptions options) where T : class { _cache.Set(key, value, options); } public void ClearCache(string key) { _cache.Remove(key); } } } |
Airline.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System.ComponentModel.DataAnnotations; namespace InMemoryCacheCore.Models { public class Code { [Key] [Display(Name = "Airlinecode")] public string? Airlinecode { get; set; } [Display(Name = "Airline3code")] public string? Airline3code { get; set; } //Can't convert VarChar to Int32 [Display(Name = "Airlinekor")] public string? Airlinekor { get; set; } [Display(Name = "Airlineeng")] public string? Airlineeng { get; set; } } } |
CacheGetSet.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
using InMemoryCacheCore.Models; using Microsoft.Extensions.Caching.Memory; using InMemoryCacheCore.Infrastructure; namespace InMemoryCacheCore.Services02.V13 { public interface ICacheGetSet { Task<IEnumerable<Code>> CacheGet(string _cacheKey); } public class CacheGetSet : ICacheGetSet { private readonly ICacheProvider? _cacheProvider; private readonly IHttpClient _httpClient; private readonly ILogger<CacheGetSet> _logger; private const int CacheTTLInSeconds = 100; private readonly MemoryCacheEntryOptions cacheEntryOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(CacheTTLInSeconds)); private static readonly SemaphoreSlim GetUsersSemaphore = new(1, 1); public CacheGetSet(ICacheProvider? cacheProvider, IHttpClient httpClient, ILogger<CacheGetSet> logger) { _cacheProvider = cacheProvider; _httpClient = httpClient; _logger = logger; } public async Task<IEnumerable<Code>> CacheGet(string _cacheKey) { try { IEnumerable<Code>? codes = _cacheProvider?.GetFromCache<IEnumerable<Code>>(_cacheKey); if (codes == null || !codes.Any()) { codes = await _httpClient.Get(); await GetUsersSemaphore.WaitAsync(); _cacheProvider?.SetCache(_cacheKey, codes, cacheEntryOptions); GetUsersSemaphore.Release(); } return codes; } catch (Exception ex) { _logger.LogError(ex, "정보를 가져오는 동안 오류가 발생했습니다."); // If you want to re-throw the exception, use "throw;" here. return Enumerable.Empty<Code>(); } } } } |
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
using InMemoryCacheCore.Infrastructure; using InMemoryCacheCore.Services02.V13; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddHttpClient(); builder.Services.AddSingleton<ICacheProvider, CacheProvider>(); //infrastructure builder.Services.AddSingleton<IHttpClient, AirlineHttpClient>(); //infrastructure builder.Services.AddScoped<ICacheGetSet, CacheGetSet>(); //추가 builder.Services.AddMemoryCache(); 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(); |