Agent Skill
2/7/2026architecture
Service layer patterns, project responsibilities, dependency injection, and API contracts for RSSVibe. Use this skill when creating services, organizing code, or understanding project structure.
J
jakoss
2GitHub Stars
1Views
npx skills add jakoss/RSSVibe
SKILL.md
| Name | architecture |
| Description | Service layer patterns, project responsibilities, dependency injection, and API contracts for RSSVibe. Use this skill when creating services, organizing code, or understanding project structure. |
name: architecture description: Service layer patterns, project responsibilities, dependency injection, and API contracts for RSSVibe. Use this skill when creating services, organizing code, or understanding project structure.
Project Architecture
Service Layer (RSSVibe.Services)
- MUST implement all business logic in the
RSSVibe.Servicesproject - MUST define service interfaces (e.g.,
IAuthService,IFeedService) for dependency injection - MUST use command/result patterns for service operations
- Services SHOULD be organized by domain area in folders (e.g.,
Auth/,Feeds/) - MUST inject repositories,
UserManager, and other infrastructure dependencies into services - SHOULD use primary constructors for service classes
- Service implementations MUST be
internal sealed(only interfaces and models arepublic) - Each project MUST provide an
IServiceCollectionextension method to register its services
Project Responsibilities
| Project | Responsibility |
|---|---|
RSSVibe.Contracts | API request/response DTOs, shared domain models |
RSSVibe.Services | Business logic, validation, orchestration |
RSSVibe.Data | Entity models, DbContext, configurations, migrations |
RSSVibe.ApiService | Minimal API endpoints, routing, middleware |
RSSVibe.Web | Blazor UI components and pages |
Service Layer Patterns
// Service interface (PUBLIC)
public interface IAuthService
{
Task<RegisterUserResult> RegisterUserAsync(RegisterUserCommand command, CancellationToken ct);
}
// Service implementation with primary constructor (INTERNAL SEALED)
internal sealed class AuthService(
UserManager<ApplicationUser> userManager,
ILogger<AuthService> logger) : IAuthService
{
public async Task<RegisterUserResult> RegisterUserAsync(
RegisterUserCommand command,
CancellationToken ct)
{
// Business logic here
}
}
// Command model (PUBLIC - in same file as service or separate Commands/ folder)
public sealed record RegisterUserCommand(
string Email,
string Password,
string DisplayName,
bool MustChangePassword
);
// Result model (PUBLIC - in same file as service or separate Results/ folder)
public sealed record RegisterUserResult
{
public bool Success { get; init; }
public Guid UserId { get; init; }
public string? Email { get; init; }
public RegistrationError? Error { get; init; }
}
Service Registration Pattern
Each project MUST provide an extension method to register its services
Location: {ProjectName}/Extensions/ServiceCollectionExtensions.cs
// In RSSVibe.Services/Extensions/ServiceCollectionExtensions.cs
namespace RSSVibe.Services.Extensions;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddRssVibeServices(this IServiceCollection services)
{
// Register all services from this project
services.AddScoped<IAuthService, AuthService>();
services.AddScoped<IFeedService, FeedService>();
// ... other services
return services;
}
}
// In Program.cs (RSSVibe.ApiService)
builder.Services.AddRssVibeServices(); // Single call registers all services
Benefits:
- Encapsulates service registration logic within each project
Program.csremains clean with single method calls per project- Internal implementations hidden from consuming projects
- Easy to maintain and test service registration
Dependency Injection
- MUST use scoped lifetime for request-specific services
- MUST use singleton lifetime for stateless services
- MUST register services via extension methods (e.g.,
AddRssVibeServices()) - Extension methods SHOULD be named
Add{ProjectName}(e.g.,AddRssVibeServices,AddRssVibeDatabase) - Service implementations MUST be
internal sealedto prevent external instantiation
API Contracts
- MUST define all API request/response models in the
RSSVibe.Contractsproject - API contracts are shared between frontend and backend services via project reference
- MUST use positional records for all contract models (immutability and clarity)
- MUST document contract changes in commit messages and ADRs when adding new endpoints or modifying existing ones
- Contracts include DTOs for API requests, responses, and domain models exposed to clients
- Shared contracts like
PagingDtoare placed in the rootRSSVibe.Contractsnamespace and reused across multiple feature areas (e.g., Feeds, FeedAnalyses, FeedItems) to ensure consistency
Skills Info
Original Name:architectureAuthor:jakoss
Download