C# coding standard for Cadtastic Solutions.
View the Project on GitHub Cadtastic-Solutions/C-Sharp-Coding-Standard
This standard defines an organized, maintainable structure for single-project applications that balances simplicity with good architectural practices.
ProjectName/ # Project root
├── Abstractions/ # [Required] Core abstractions
│ ├── Interfaces/ # Interfaces defining contracts
│ └── Base/ # Base/abstract classes
│
├── Models/ # [Required] Data models
│ ├── Entities/ # Database entities
│ ├── DTOs/ # Data transfer objects
│ ├── Enums/ # Enumeration types
│ └── ViewModels/ # UI view models
│
├── Services/ # [Required] Business logic
│ ├── Interfaces/ # Service contracts
│ └── Implementations/ # Service implementations
│
├── Data/ # [Required] Data access
│ ├── Context/ # Database context
│ ├── Repositories/ # Data access logic
│ ├── Configurations/ # Entity configurations
│ └── Migrations/ # Database migrations
│
├── Utilities/ # [Optional] Helper classes
│ ├── Extensions/ # Extension methods
│ ├── Helpers/ # Helper classes
│ └── Constants/ # Constant values
│
├── Features/ # [Required] Feature modules
│ ├── Users/ # User management feature
│ │ ├── Controllers/ # Feature controllers
│ │ ├── Views/ # Feature views
│ │ └── Services/ # Feature-specific services
│ └── Products/ # Product management feature
│ ├── Controllers/
│ ├── Views/
│ └── Services/
│
├── wwwroot/ # [Web Only] Static files
│ ├── css/
│ ├── js/
│ └── lib/
│
├── Views/ # [MVC Only] Shared views
│ └── Shared/ # Shared view components
│
├── docs/ # [Required] Documentation
│ ├── index.md
│ ├── getting-started/
│ ├── guides/
│ └── api/
│
├── build/ # [Optional] Build files
├── .gitattributes # [Required] Git attributes
├── .gitignore # [Required] Git ignore rules
├── README.md # [Required] Project overview
└── LICENSE.txt # [Required] License information
// Features/Users/Controllers/UserController.cs
public class UserController : Controller
{
private readonly IUserService _userService;
public async Task<IActionResult> List()
{
var users = await _userService.GetAllAsync();
return View(users);
}
}
// Features/Users/Services/UserService.cs
public class UserService : IUserService
{
private readonly ApplicationDbContext _context;
public async Task<List<UserDto>> GetAllAsync()
{
var users = await _context.Users.ToListAsync();
return users.Select(u => u.ToDto()).ToList();
}
}
// Abstractions/Interfaces/IRepository.cs
public interface IRepository<T> where T : class
{
Task<T> GetByIdAsync(int id);
Task<List<T>> GetAllAsync();
Task AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(int id);
}
// Abstractions/Base/BaseEntity.cs
public abstract class BaseEntity
{
public int Id { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
}
// Models/Entities/User.cs
public class User : BaseEntity
{
public string Username { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
}
// Models/DTOs/UserDto.cs
public class UserDto
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
// Models/ViewModels/UserViewModel.cs
public class UserViewModel
{
public string Username { get; set; }
public string Email { get; set; }
public List<string> Roles { get; set; }
}
// Data/Context/ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
}
}
// Data/Repositories/UserRepository.cs
public class UserRepository : IRepository<User>
{
private readonly ApplicationDbContext _context;
public async Task<User> GetByIdAsync(int id)
{
return await _context.Users.FindAsync(id);
}
}
// Services/Interfaces/IUserService.cs
public interface IUserService
{
Task<UserDto> GetByIdAsync(int id);
Task<List<UserDto>> GetAllAsync();
Task<UserDto> CreateAsync(CreateUserDto dto);
}
// Services/Implementations/UserService.cs
public class UserService : IUserService
{
private readonly IRepository<User> _repository;
public async Task<UserDto> GetByIdAsync(int id)
{
var user = await _repository.GetByIdAsync(id);
return user?.ToDto();
}
}
// Program.cs
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IRepository<User>, UserRepository>();
}
}
// Utilities/Extensions/ServiceCollectionExtensions.cs
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddApplicationServices(
this IServiceCollection services)
{
services.AddScoped<IUserService, UserService>();
services.AddScoped<IEmailService, EmailService>();
return services;
}
}
Consider migrating to Clean Architecture when: