Caffeine.Generators API
개요
Caffeine.Generators는 Roslyn Source Generator 기반의 컴파일 타임 코드 생성 패키지입니다. [Packet] 어트리뷰트가 붙은 클래스에 대해 고성능 직렬화 메서드를 자동으로 생성하여, 반복적인 보일러플레이트 코드를 제거하고 Zero-Allocation 아키텍처를 지원합니다.
Caffeine 내 역할
드라이버 통신 패킷, 브릿지 IPC 메시지 등 반복적인 직렬화 로직을 Source Generator로 자동 생성합니다.
기본 정보
| 항목 | 값 |
|---|---|
| 패키지 | NEXCODE.Caffeine.Generators |
| 타겟 프레임워크 | netstandard2.0 |
| 의존성 | Microsoft.CodeAnalysis.CSharp |
| Generator 클래스 | PacketSourceGenerator |
| 생성 파일 패턴 | {ClassName}_Packet.g.cs |
설치
<ItemGroup>
<!-- Roslyn Source Generator는 Analyzer 경로로 참조 -->
<ProjectReference Include="..\Caffeine.Generators\Caffeine.Generators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
NuGet 배포 버전 사용 시:
dotnet add package NEXCODE.Caffeine.Generators
<PackageReference Include="NEXCODE.Caffeine.Generators" Version="2.0.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
PacketSourceGenerator
동작 원리
- 컴파일 타임에
[Packet]어트리뷰트가 붙은partial class를 탐색 - 해당 클래스에 대해
{ClassName}_Packet.g.cs파일 생성 - 생성된 파일에
ToBytesOptimized()등의 직렬화 메서드 추가
사용법
// 1. 클래스에 [Packet] 어트리뷰트 적용 (partial 필수)
[Packet]
public partial class ModbusReadPacket
{
public byte FunctionCode { get; set; }
public ushort StartAddress { get; set; }
public ushort Quantity { get; set; }
}
// 2. 컴파일 후 자동 생성된 메서드 사용
var packet = new ModbusReadPacket
{
FunctionCode = 0x03,
StartAddress = 0x0000,
Quantity = 10
};
byte[] bytes = packet.ToBytesOptimized();
생성 코드 구조
// <auto-generated/>
// ModbusReadPacket_Packet.g.cs
using System;
using System.Buffers;
namespace YourNamespace
{
public partial class ModbusReadPacket
{
public byte[] ToBytesOptimized()
{
// 프로퍼티 기반 고성능 직렬화 코드
return new byte[10];
}
}
}
어트리뷰트 참조
[Packet]
Source Generator 처리 대상임을 표시합니다.
요구사항:
- 클래스에
partial키워드 필수 - 어트리뷰트가 없으면 코드 생성 미적용
// ✅ 올바른 사용
[Packet]
public partial class MyPacket { }
// ❌ partial 없으면 동작 안 함 (컴파일 오류)
[Packet]
public class MyPacket { }
사용 예제
드라이버 패킷 정의
using Caffeine.Generators;
namespace Caffeine.Drivers.Modbus.Packets;
[Packet]
public partial class ModbusReadCoilsPacket
{
public byte DeviceId { get; set; }
public byte FunctionCode { get; set; } = 0x01;
public ushort StartAddress { get; set; }
public ushort CoilCount { get; set; }
}
[Packet]
public partial class ModbusWriteCoilPacket
{
public byte DeviceId { get; set; }
public byte FunctionCode { get; set; } = 0x05;
public ushort CoilAddress { get; set; }
public ushort Value { get; set; }
}
생성된 코드 활용
var readPacket = new ModbusReadCoilsPacket
{
DeviceId = 1,
StartAddress = 0x0100,
CoilCount = 8
};
// Source Generator가 생성한 메서드 호출
byte[] frame = readPacket.ToBytesOptimized();
await _tcpStream.WriteAsync(frame, cancellationToken);
xUnit 테스트
public class ModbusPacketTests
{
[Fact]
public void ToBytesOptimized_ShouldReturnNonEmptyArray()
{
var packet = new ModbusReadCoilsPacket
{
DeviceId = 1,
StartAddress = 0x0100,
CoilCount = 8
};
var bytes = packet.ToBytesOptimized();
Assert.NotNull(bytes);
Assert.True(bytes.Length > 0);
}
}
제한사항
| 제한 | 설명 |
|---|---|
| 타겟 프레임워크 | netstandard2.0 (호스트 프로젝트와 무관) |
partial 키워드 | [Packet] 클래스에 필수 |
| IDE 재시작 | Generator 변경 후 IDE(Visual Studio/Rider) 재시작 필요할 수 있음 |
| 중첩 클래스 | 중첩 클래스(nested class)에는 적용 불가 |
| 제네릭 클래스 | 현재 버전에서 제네릭 타입 파라미터 미지원 |
IDE 설정
Visual Studio
Tools > Options > Text Editor > C# > Advanced:
- "Show completion list in argument lists" 활성화
- Roslyn Analyzer 경고 수준 조정
Visual Studio Code (C# Dev Kit)
Source Generator로 생성된 파일은 Analyzers 노드에서 확인 가능:
솔루션 탐색기
└── 참조
└── 분석기
└── Caffeine.Generators
└── ModbusReadCoilsPacket_Packet.g.cs