← Back to list

architecture
by YosrBennagra
⭐ 1🍴 0📅 Jan 21, 2026
SKILL.md
name: architecture description: Clean architecture patterns for the 3SC widget host. Defines layer boundaries, dependency rules, composition root patterns, and abstraction strategies.
Architecture
Overview
3SC follows Clean Architecture principles adapted for a WPF desktop application. This ensures testability, maintainability, and clear separation of concerns.
Layer Structure
┌─────────────────────────────────────────────────────────────┐
│ 3SC.UI │
│ • WPF Views & Windows │
│ • ViewModels (CommunityToolkit.Mvvm) │
│ • UI Services (Navigation, Dialogs) │
│ • Composition Root (ServiceLocator) │
├─────────────────────────────────────────────────────────────┤
│ 3SC.Application │
│ • Repository Interfaces │
│ • Service Abstractions │
│ • DTOs / Request-Response Models │
│ • Use Case Orchestration (future) │
├─────────────────────────────────────────────────────────────┤
│ 3SC.Infrastructure │
│ • EF Core DbContext & Repositories │
│ • External API Clients │
│ • File System Operations │
│ • Security Implementations │
├─────────────────────────────────────────────────────────────┤
│ 3SC.Domain │
│ • Entities (Widget, Layout, etc.) │
│ • Value Objects (WidgetSize, WidgetPosition) │
│ • Domain Rules & Validation │
│ • No External Dependencies │
└─────────────────────────────────────────────────────────────┘
Dependency Rules
| Layer | Can Reference | Cannot Reference |
|---|---|---|
| Domain | Nothing | Everything else |
| Application | Domain | Infrastructure, UI |
| Infrastructure | Domain, Application | UI |
| UI | All layers | - |
Definition of Done (DoD)
- New types are in the correct layer
- Domain has no external package references
- Infrastructure types implement Application interfaces
- ViewModels depend on interfaces, not implementations
- No circular dependencies between projects
- Composition happens only in ServiceLocator
Composition Root Pattern
All dependencies are wired in ServiceLocator.cs:
public sealed class ServiceLocator : IDisposable
{
// Use Lazy<T> for deferred initialization
private readonly Lazy<IWidgetRepository> _widgetRepository;
private ServiceLocator()
{
// Wire dependencies in constructor
_widgetRepository = new Lazy<IWidgetRepository>(() =>
new WidgetRepository(DbContext));
}
public IWidgetRepository WidgetRepository => _widgetRepository.Value;
}
Best Practices
- Register interfaces, not implementations
- Use Lazy for expensive services
- Avoid service location in ViewModels - inject via constructor
- Dispose resources properly - implement IDisposable chain
Abstraction Strategy
When to Abstract
| Scenario | Abstract? | Example |
|---|---|---|
| External dependencies | ✅ Yes | File system, HTTP, time |
| Infrastructure concerns | ✅ Yes | Database, caching |
| Cross-cutting concerns | ✅ Yes | Logging, telemetry |
| Simple utilities | ❌ No | String helpers, math |
| Framework types | ❌ No | List, Dictionary<K,V> |
Required Abstractions
// These MUST be abstracted for testability:
public interface IDateTimeProvider
{
DateTimeOffset UtcNow { get; }
DateTimeOffset Now { get; }
}
public interface IFileSystem
{
bool FileExists(string path);
bool DirectoryExists(string path);
string[] GetFiles(string path, string searchPattern);
string ReadAllText(string path);
void WriteAllText(string path, string content);
Stream OpenRead(string path);
}
public interface IEnvironmentProvider
{
string GetFolderPath(Environment.SpecialFolder folder);
string MachineName { get; }
string UserName { get; }
}
Cross-Cutting Concerns
Logging
- Inject
ILogger<T>via constructor - Use structured logging with Serilog
- Include correlation IDs for request tracing
Validation
- Domain validation in entities (guard clauses)
- Input validation in ViewModels (ObservableValidator)
- API validation in Infrastructure (data annotations)
Error Handling
- Domain: Throw domain exceptions
- Application: Catch and translate to results
- Infrastructure: Wrap external errors
- UI: Display user-friendly messages
Anti-Patterns to Avoid
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Service Locator in VMs | Hidden dependencies, hard to test | Constructor injection |
| Static dependencies | Global state, race conditions | Instance methods, DI |
| God classes | Too many responsibilities | Single Responsibility |
| Leaky abstractions | Infrastructure in domain | Clean interfaces |
| Anemic domain | Logic outside entities | Rich domain model |
Project References
3SC.UI
├── 3SC.Application
├── 3SC.Infrastructure
└── 3SC.Domain
3SC.Application
└── 3SC.Domain
3SC.Infrastructure
├── 3SC.Application
└── 3SC.Domain
3SC.Domain
└── (no references)
Testing Strategy
- Domain: Unit tests, no mocks needed
- Application: Unit tests with mocked interfaces
- Infrastructure: Integration tests with test database
- UI/ViewModels: Unit tests with mocked services
References
Score
Total Score
40/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
Reviews
💬
Reviews coming soon