플러그인 시스템
플러그인으로 뷰어 확장
Doconut의 핵심은 간결하게 유지됩니다; 선택적 기능은 플러그인 — 뷰어나 서비스를 제공하는 별도의 NuGet 패키지이며 라이선스로 활성화됩니다. 이 페이지에서는 등록 모델, 런타임에서 라이선스 게이팅이 어떻게 동작하는지, 그리고 자체 뷰어를 어떻게 연결하는지 설명합니다.
이 모델은 이번 릴리스에서 새롭게 도입되었습니다. 이전 .NET Standard 라이브러리에는 플러그인 레지스트리가 없었습니다: 변환은 뷰어 자체에 있었고 플러그인 라이선스는 정적 Viewer.SetLicensePlugin(...) 호출을 통해 설치되었습니다. 여기서는 등록 메커니즘이 존재하지 않습니다.
플러그인 등록
각 플러그인 패키지는 하나의 플러그인 클래스를 노출합니다. 시작 시 한 번 등록합니다:
builder.Services.AddDoconut(options =>
{
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});AddPlugin<TPlugin>() 은 플러그인을 인스턴스화하고 DoconutOptions 에 보관된 플러그인 레지스트리에 대해 플러그인의 Register 콜백을 호출합니다. 플러그인이 제공하는 모든 것은 플러그인의 필수 기능 으로 태그됩니다. AddDoconut() 은 등록된 플러그인을 즉시 검증합니다: 라이선스가 없거나, 레거시 TRIAL 파일이 있거나, 해당 기능이 없는 유료 라이선스는 InvalidOperationException 로 시작이 실패합니다. Temporary/Demo 등록은 만료 후에도 유지되지만, 런타임 기능은 만료일 이후에 회수됩니다.
계약
플러그인은 의도적으로 작은 인터페이스를 구현합니다:
public interface IDoconutPlugin
{
string Name { get; } // 예: "Doconut DICOM Viewer"
LicenseCapability RequiredCapability { get; } // 라이선스 게이트
void Register(IDoconutPluginBuilder builder); // 뷰어/서비스 기여
}Register 내부에서, 빌더는 두 종류의 기여를 허용합니다:
builder.RegisterViewer(".dcm", () => new DicomViewer())— 파일 확장자를 위한 뷰어,builder.RegisterService<TContract>(() => …)— 파이프라인의 다른 부분에서 조회할 수 있는 타입화된 서비스.
기능 및 게이팅
기능은 라이선스 단위입니다. Converter 와 Dicom 은 선택적 플러그인으로 제공됩니다; Search 와 Annotation 은 동일한 방식으로 게이팅되는 기본 제공 기능입니다. 기본 뷰어는 기능이 아닙니다 — 전제 조건이며, 라이선스 서비스에서 IsViewerLicensed 로 노출됩니다.
시작 시 검증은 일반적으로 라이선스가 없는 플러그인이 요청 파이프라인에 진입하는 것을 방지합니다. 뷰어 팩토리 또한 두 가지 방어적 런타임 규칙을 적용하는데, 이는 시작 후 권한이 변경될 경우 중요합니다:
- 플러그인이 기본 제공 뷰어를 대체 (플러그인이 기본 레지스트리에서도 처리하는 확장자를 주장함): 기능이 라이선스된 경우 플러그인 뷰어가 우선합니다; 그렇지 않으면 Doconut이 조용히 기본 제공 뷰어로 돌아갑니다. 사용자는 여전히 문서를 볼 수 있지만 플러그인 기능은 제공되지 않습니다.
- 플러그인 전용 포맷 (예:
.dcm— DICOM은 기본 제공 뷰어가 없음): 기능이 없으면 열기 호출이 강제로 실패합니다:
LicenseException: This document type requires the 'Dicom' plugin license.활성화된 Temporary 라이선스는 모든 기능을 부여합니다 (깨끗하고 워터마크가 없는 기본 뷰잉). 이는 실서비스 시 흔히 발생하는 놀라움의 원인입니다: 기능 중 하나가 누락된 구매 라이선스로 동일한 플러그인을 등록하면 AddDoconut() 가 시작 시 실패합니다. 배포 전에 IsCapabilityGranted(...) 를 플랜과 비교하십시오. 반대로 라이선스가 전혀 없으면, 아무 것도 부여되지 않습니다 — 라이선스가 없다는 것은 Temporary 라이선스가 아니라는 의미입니다.
같은 게이팅이 클라이언트 측에서도 나타납니다: Viewer.ReferenceScripts() 와 ReferenceCss() 은 라이선스가 해당 기능을 활성화할 때만 (검색, 주석 등) 스크립트/스타일 번들을 내보냅니다, 따라서 위젯 UI가 서버가 실제로 수행하는 내용과 일치하게 유지됩니다.
기능 및 플러그인 맵
제품 UI는 "플러그인"을 광범위한 기능 라벨로 사용하지만, 서버 등록은 다릅니다:
| 기능 | 활성화 방법 | 기능 | 기여 내용 |
|---|---|---|---|
| 주석 | 뷰어에 기본 포함; 주석 리소스 포함 | Annotation | 브라우저 저작, 세션 지속성 및 내장형 내보내기 |
| 검색 | 검색 가능한 형식 뷰어에 기본 포함; 검색 리소스를 포함하고 필요 시 추출을 활성화 | Search | 네이티브 텍스트 인덱스, 하이라이트 및 결과 탐색 |
| 변환기 | Doconut.NETStandard.Converter 를 설치하고 ConverterPlugin 를 등록 | Converter | C# 변환 서비스 및 선택적 웹 위젯 |
| DICOM | Doconut.NETStandard.Dicom 를 설치하고 DicomPlugin 를 등록 | Dicom | .dcm 및 .ima 용 의료 이미지 뷰잉 |
주석과 일반 검색은 AddPlugin<TPlugin>() 를 사용하지 않습니다; 해당 번들은 라이선스가 해당 기능을 부여할 때만 내보내집니다. 변환기와 DICOM은 이 문서 세트에 대한 출시된 선택적 IDoconutPlugin 구현입니다.
승인된 .NET Standard 아티팩트에는 핵심 패키지와 동일한 버전의 Doconut.NETStandard.Converter 와 Doconut.NETStandard.Dicom 가 포함됩니다.
출시된 플러그인 패키지
| 플러그인 | 패키지 | 기능 | 기여 내용 |
|---|---|---|---|
| 변환기 | Doconut.NETStandard.Converter | Converter | 문서 변환 기능 |
| DICOM | Doconut.NETStandard.Dicom | Dicom | .dcm (플러그인 전용 포맷) 용 의료 이미지 뷰잉 |
각각은 플러그인 섹션 아래 전용 페이지가 있으며, 구성 및 사용법을 제공합니다.
맞춤 뷰어 — 자체 포맷 핸들러
플러그인 패키지를 작성하지 않고도 Program.cs 로부터 직접 파이프라인에 뷰어를 연결할 수 있습니다:
builder.Services.AddDoconut(options =>
{
options.RegisterViewer(
".myext",
() => new MyCustomViewer(), // 구현 IFormatViewer
() => new ImageConfig { ImageResolution = 150 }); // 옵션 기본 구성
});맞춤 뷰어는 모든 것 — 기본 제공 및 플러그인 모두 — 위에 우선 순위를 가지며 라이선스 게이팅되지 않습니다(사용자 코드이기 때문). 기본 구성을 제공하지 않으면 팩토리는 ImageConfig 로 대체됩니다.
요약
- 플러그인은 명시적으로 등록되며, 그들의
LicenseCapability은AddDoconut()동안 검증됩니다 — 누락되었거나 일시적이 아닌 권한이 충분하지 않으면 즉시 실패합니다. - 오버라이드 스타일 플러그인은 우아하게 감소하고; 플러그인 전용 포맷은
LicenseException로 실패합니다. - 활성화된 Temporary 라이선스는 모든 것을 잠금 해제하고, 프로덕션 라이선스는 구매한 항목만 잠금 해제합니다. 배포 전에
IDoconutLicenseService로 확인하십시오.
이 페이지가 도움이 되었나요?