기본 클래스 라이브러리 (BCL)
Base Class Library는 .NET 애플리케이션 개발의 기반이 되는 표준 라이브러리 모음입니다. Windows 플랫폼과 함께 성장하여 현재는 .NET 환경의 핵심 API 역할을 수행합니다.
핵심 네임스페이스
| 네임스페이스 | 주요 기능 |
|---|---|
| System | 애플리케이션 도메인, 기본 데이터 타입, 입출력 서비스 |
| System.Collections.Generic | 제네릭 기반 컬렉션 및 데이터 구조 |
| System.Configuration | 애플리케이션 설정 관리 |
| System.ComponentModel | 컴포넌트 아키텍처 지원 |
| System.Data | ADO.NET 데이터 접근 핵심 기능 |
| System.Drawing | GDI/GDI+ 기반 그래픽 처리 및 인 |
| System.IO | 파일, 스트림, 압축, 파이프 처리 |
| System.Net | HTTP, FTP, TCP/UDP, SMTP 네트워크 통신 |
| System.Reflection | 런타임 타입 정보 및 동적 객체 조작 |
| System.Diagnostics | 디버깅, 추적, 프로세스 관리 |
| System.Security | 암호화, 인증, 코드 접근 보안 |
| System.Text | 인코딩, 정규표현식 처리 |
| System.Threading | 스레드 및 동기화 제어 |
| System.Linq | LINQ 쿼리 기능 (.NET 3.5+) |
| System.Xml.Linq | LINQ to XML (.NET 3.5+) |
IO 스트림 클래스 상세
// 텍스트 기반 입출력
var reader = new StreamReader("data.txt");
var writer = new StreamWriter("output.txt");
// 바이너리 데이터 처리
var binaryIn = new BinaryReader(File.OpenRead("binary.dat"));
var binaryOut = new BinaryWriter(File.OpenWrite("result.dat"));
// 메모리 기반 스트림
using var memStream = new MemoryStream(buffer);
// 파일 스트림 with 버퍼링
var buffered = new BufferedStream(new FileStream("large.bin", FileMode.Open));
// 압축 처리 (GZip/Deflate)
using var gzip = new GZipStream(sourceStream, CompressionMode.Compress);
인기 서드파티 NuGet 패키지
API 문서화: Swashbuckle.AspNetCore
ASP.NET Core Web API의 OpenAPI(Swagger) 문서를 자동 생성하는 도구입니다.
// Program.cs 구성 예시
builder.Services.AddSwaggerGen(options => {
options.SwaggerDoc("v1", new OpenApiInfo {
Title = "My API",
Version = "1.0"
});
// XML 주석 기반 문서화
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFile));
});
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1"));
이메일 전송: FluentEmail
Razor 템플릿 기반 이메일 발송을 지원하는 라이브러리입니다.
// SMTP 설정
var smtpSender = new SmtpSender(() => new SmtpClient("smtp.server.com") {
Port = 587,
Credentials = new NetworkCredential("user", "pass"),
EnableSsl = true
});
// 의존성 주입 구성
services.AddFluentEmail("sender@domain.com")
.AddRazorRenderer()
.AddSmtpSender(smtpSender);
// 메일 발송 예시
await emailFactory
.Create()
.To("recipient@example.com")
.Subject("주문 확인")
.UsingTemplateFromFile("Templates/OrderConfirmation.cshtml", orderModel)
.SendAsync();
단위 테스트: xUnit
.NET 진영에서 가장 널리 사용되는 테스트 프레임워크입니다.
public class CalculatorTests {
private readonly Calculator _calc = new();
[Fact]
public void Add_TwoNumbers_ReturnsSum() {
var result = _calc.Add(2, 3);
Assert.Equal(5, result);
}
[Theory]
[InlineData(1, 1, 2)]
[InlineData(-1, 1, 0)]
[InlineData(int.MaxValue, 1, int.MaxValue)] // 오버플로우 케이스
public void Add_VariousInputs_ReturnsExpected(int a, int b, int expected) {
Assert.Equal(expected, _calc.Add(a, b));
}
}
애플리케이션 메트릭: App.Metrics
InfluxDB, Grafana와 연동하여 성능 모니터링 대시보드를 구성할 수 있습니다.
// 메트릭 수집기 초기화
var metrics = new MetricsBuilder()
.Report.ToInfluxDb(options => {
options.InfluxDb.BaseUri = new Uri("http://localhost:8086");
options.InfluxDb.Database = "app_metrics";
})
.Build();
// 카운터 증가
metrics.Measure.Counter.Increment(new CounterOptions { Name = "user_logins" });
// 타이머로 실행 시간 측정
using (metrics.Measure.Timer.Time(new TimerOptions { Name = "db_query_time" })) {
await repository.GetDataAsync();
}
해시 알고리즘: HashLib
다양한 해시 알고리즘 구현체를 제공합니다.
var hasher = HashFactory.Crypto.CreateSHA256();
var hashResult = hasher.ComputeString("input data");
var hexString = hashResult.ToHex();
객체 매핑: AutoMapper
엔티티와 DTO 간의 변환을 자동화합니다.
// 매핑 프로필 정의
public class OrderProfile : Profile {
public OrderProfile() {
CreateMap<OrderEntity, OrderDto>()
.ForMember(dest => dest.TotalAmount,
opt => opt.MapFrom(src => src.Items.Sum(i => i.Price * i.Quantity)))
.ForMember(dest => dest.CustomerName,
opt => opt.MapFrom(src => $"{src.Customer.FirstName} {src.Customer.LastName}"));
}
}
// 사용 예시
var dto = mapper.Map<OrderDto>(entity);
ORM 도구
| 패키지 | 특징 | 적합한 상황 |
|---|---|---|
| Entity Framework Core | 풀기능 ORM, 마이그레이션, 변경 추적 | 복잡한 도메인 모델, 코드 스트 개발 |
| Dapper | 마이크로 ORM, 고성능, 수동 SQL | 단순 쿼리, 성능이 중요한 경우 |
| SqlSugar | 국산 경량 ORM, LINQ 지원 | 중소형 프로젝트, 빠른 개발 |
| Massive | 단 2개 파일, 동적 객체 | 매우 가벼운 솔루션 필요 시 |
회복력 패턴: Polly
분산 시스템에서 필수적인 장애 대응 패턴을 구현합니다.
// 재시도 정책: 3번 시도, 지수 백오프
var retryPolicy = Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(3, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
onRetry: (ex, delay) => logger.LogWarning($"재시도, 지연: {delay}s"));
// 서킷 브레이커: 5번 실패 후 30초 차단
var circuitBreaker = Policy
.Handle<HttpRequestException>()
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
// 타임아웃 + 대체(fallback) 조합
var resiliencePolicy = Policy.WrapAsync(
Policy.Handle<TimeoutException>().FallbackAsync(defaultValue),
Policy.TimeoutAsync<TResult>(TimeSpan.FromSeconds(10)),
retryPolicy,
circuitBreaker
);
기본 타입 활용 가이드
String vs StringBuilder
// ❌ 비율적: 루프 내 문자열 연결
string result = "";
for (int i = 0; i < 10000; i++) {
result += i.ToString(); // 매번 새 객체 생성
}
// ✅ 효율적: StringBuilder 사용
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.Append(i);
}
var result = sb.ToString();
// ✅ 메서드 체이
var formatted = new StringBuilder()
.Append("User: ").Append(userName)
.Append(", Age: ").Append(age)
.ToString();
DateTime/DateTimeOffset 활용
// 현재 시간 (로컬 vs UTC)
DateTime localNow = DateTime.Now; // 로컬 시간대
DateTime utcNow = DateTime.UtcNow; // 협정 세계시
// 시간대 변환
DateTimeOffset koreanTime = DateTimeOffset.Now;
DateTimeOffset nyTime = koreanTime.ToOffset(TimeSpan.FromHours(-5));
// 시간 연산
var tomorrow = DateTime.Today.AddDays(1);
var nextMonth = DateTime.Now.AddMonths(1);
var timeDiff = endTime - startTime; // TimeSpan 반환
// 파싱
if (DateTime.TryParse("2024-01-15", out var parsedDate)) {
// 성공 시 처리
}
Timer 구현 패턴
// System.Timers.Timer 사용
var timer = new System.Timers.Timer {
Interval = 5000, // 5초
AutoReset = true
};
timer.Elapsed += async (sender, e) => {
await ProcessScheduledTaskAsync();
};
// 또는 async void 피하기
timer.Elapsed += async (sender, e) => {
try {
timer.Stop(); // 중복 실행 방지
await ProcessScheduledTaskAsync();
}
finally {
timer.Start();
}
};
timer.Start();
파일 시스템 조작
Path 유틸리티
var fullPath = Path.Combine(@"C:\Projects", "Data", "config.json");
var fileName = Path.GetFileName(fullPath); // "config.json"
var nameOnly = Path.GetFileNameWithoutExtension(fullPath); // "config"
var extension = Path.GetExtension(fullPath); // ".json"
var directory = Path.GetDirectoryName(fullPath); // @"C:\Projects\Data"
var tempFile = Path.GetTempFileName(); // 임시 파일 생성
File/Directory 작업
// 파일 작업
await File.WriteAllTextAsync("log.txt", content, Encoding.UTF8);
var lines = await File.ReadAllLinesAsync("data.csv");
await File.AppendAllTextAsync("log.txt", newEntry);
// 디렉토리 작업
Directory.CreateDirectory(@"C:\Backup\2024");
var files = Directory.EnumerateFiles(sourceDir, "*.txt", SearchOption.AllDirectories);
// 대용량 파일 처리 (스트리밍)
await using var stream = File.OpenRead("huge.zip");
var buffer = new byte[8192];
int read;
while ((read = await stream.ReadAsync(buffer)) > 0) {
await output.WriteAsync(buffer.AsMemory(0, read));
}
시리얼라이제이션 옵션
| 라이브러리 | 특징 | 사용 예시 |
|---|---|---|
| System.Text.Json | NET Core 3.0+ 기본, 고성능 | JsonSerializer.Serialize(obj) |
| Newtonsoft.Json | 기능 부, 유연한 설정 | JsonConvert.SerializeObject(obj) |
| Jil | 직렬화 성능 최적화 | JSON.Serialize(obj) |
| MessagePack | 바이너리 포맷, 고성능 | MessagePackSerializer.Serialize(obj) |
로깅 인프라
// Microsoft.Extensions.Logging (권장)
services.AddLogging(builder => {
builder.AddConsole();
builder.AddDebug();
builder.AddFile("logs/app-{Date}.txt"); // Serilog 또는 NLog 연동
});
// NLog 구성 예시
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
logger.Info("애플리케이션 시작");
// Serilog + 구조적 로깅
Log.Logger = new LoggerConfiguration()
.WriteTo.Console(new JsonFormatter())
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://es:9200")))
.CreateLogger();
기타 유용한 패키지
| 분류 | 패키지명 | 용도 |
|---|---|---|
| 캐싱 | StackExchange.Redis | Redis 연동 |
| 검색 | NEST (Elasticsearch) | ElasticSearch .NET 클라이언트 |
| 메시징 | RabbitMQ.Client | AMQP 메시지 브로커 |
| 스케줄링 | Quartz | 크론 기반 작업 예약 |
| 유효성검사 | FluentValidation | 선언적 검증 규칙 |
| HTTP | Refit | 타입 안전 REST 클라이언트 |
| iTextSharp / PdfSharp | PDF 생성 및 조작 |