메서드에 캐싱 기능을 적용할 때, Attribute를 활용하면 코드의 가독성과 재사용성을 높일 수 있습니다. 이번 글에서는 C#에서 Attribute를 이용해 간단한 메서드 캐싱을 구현하는 방법을 소개합니다.
1. 캐시용 Attribute 정의
먼저 캐싱이 적용될 메서드에 사용할 Attribute 클래스를 만듭니다.
[AttributeUsage(AttributeTargets.Method)]
public class CacheAttribute : Attribute
{
public int DurationSeconds { get; }
public CacheAttribute(int durationSeconds = 60)
{
DurationSeconds = durationSeconds;
}
}
2. 메서드 캐싱 로직 작성
반복 호출되는 메서드 결과를 저장하는 딕셔너리를 만들고, 캐시 유효 시간을 체크합니다.
using System;
using System.Collections.Concurrent;
using System.Reflection;
public static class CacheManager
{
private static ConcurrentDictionary _cache
= new ConcurrentDictionary<string, (object, DateTime)>();
public static T GetOrAdd<T>(MethodInfo method, object[] args, Func<T> factory, int duration)
{
string key = GetCacheKey(method, args);
if (_cache.TryGetValue(key, out var cached))
{
if (cached.Expiry > DateTime.Now)
return (T)cached.Value;
_cache.TryRemove(key, out _);
}
T result = factory();
_cache[key] = (result, DateTime.Now.AddSeconds(duration));
return result;
}
private static string GetCacheKey(MethodInfo method, object[] args)
{
string argKey = string.Join("_", args ?? Array.Empty<object>());
return $"{method.DeclaringType.FullName}.{method.Name}_{argKey}";
}
}
3. Attribute 적용 및 호출 예시
캐싱 기능을 메서드 호출시 적용하는 예시입니다. 리플렉션과 Delegate를 활용할 수 있습니다.
using System.Reflection;
public class SampleService
{
[Cache(30)]
public int Compute(int x, int y)
{
Console.WriteLine("실제 메서드 실행");
return x + y;
}
public int ComputeWithCache(int x, int y)
{
MethodInfo method = typeof(SampleService).GetMethod(nameof(Compute));
var attr = method.GetCustomAttribute<CacheAttribute>();
if (attr == null)
return Compute(x, y);
return CacheManager.GetOrAdd(method, new object[] { x, y }, () => Compute(x, y), attr.DurationSeconds);
}
}
위 예제에서 Compute 메서드는 캐싱이 적용되어 30초 동안 같은 인자값의 결과를 저장합니다. 실제 실행 출력은 첫 호출에만 나타납니다.
4. 마무리
Attribute 기반 캐싱은 코드 중복을 줄이고, 필요한 메서드에 쉽게 적용할 수 있는 방법입니다. 실제 프로젝트에서는 동기화, 캐시 만료, 메모리 관리 등을 추가로 고려해야 합니다.
'C#' 카테고리의 다른 글
| C# Stopwatch를 활용한 코드 블록별 성능 분석 (0) | 2026.07.03 |
|---|---|
| C# StreamReader와 StreamWriter의 고급 활용 (0) | 2026.07.03 |
| C# 애플리케이션 도메인(AppDomain) 관리와 활용 (0) | 2026.07.02 |
| C# ConcurrentDictionary를 이용한 안전한 데이터 공유 (1) | 2026.07.01 |
| C# 인터페이스 다중 상속 시 충돌 해결 전략 (0) | 2026.06.30 |