Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to this project.
- Code of Conduct
- Getting Started
- How to Contribute
- Development Setup
- Coding Standards
- Testing Guidelines
- Pull Request Process
- Documentation
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to dogaaydinn@gmail.com.
- .NET 8 SDK (8.0.201 or later)
- Git for version control
- IDE: Visual Studio 2022, Rider, or VS Code with C# extension
- Docker (optional, for running observability stack)
-
Fork the repository on GitHub
-
Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/CSharp-Covariance-Polymorphism-Exercises.git cd CSharp-Covariance-Polymorphism-Exercises -
Add upstream remote:
git remote add upstream https://github.com/dogaaydinn/CSharp-Covariance-Polymorphism-Exercises.git
- Search existing issues before creating a new one
- Use the bug report template
- Include:
- Clear description of the issue
- Steps to reproduce
- Expected vs actual behavior
- Environment details (.NET version, OS)
- Code samples or screenshots
- Use the feature request template
- Clearly describe the enhancement
- Explain why it would be valuable
- Provide examples if possible
We welcome contributions in these areas:
- New Examples: Additional C# concepts or patterns
- Bug Fixes: Fix issues in existing code
- Performance Improvements: Optimize existing examples
- Documentation: Improve guides, tutorials, or API docs
- Tests: Add missing test coverage
- Benchmarks: New performance benchmarks
# Restore dependencies
dotnet restore
# Build solution
dotnet build
# Run tests
dotnet test
# Run specific test project
dotnet test tests/AdvancedConcepts.UnitTests# Run the core application
dotnet run --project src/AdvancedConcepts.Core
# Run with specific example
dotnet run --project src/AdvancedConcepts.Core -- --example polymorphism# Run all benchmarks
dotnet run --project benchmarks/AdvancedConcepts.Benchmarks -c Release
# Run specific benchmark category
dotnet run --project benchmarks/AdvancedConcepts.Benchmarks -c Release -- --filter *Boxing*# Start observability stack (Seq, Prometheus, Grafana)
docker-compose up -d
# View logs in Seq: http://localhost:5342
# View metrics in Grafana: http://localhost:3000We follow Microsoft's C# coding conventions with these tools enforcing standards:
- StyleCop.Analyzers - Code style rules
- Roslynator.Analyzers - Code quality rules
- SonarAnalyzer.CSharp - Security and code smell detection
- Meziantou.Analyzer - Best practices
- SecurityCodeScan - Security vulnerabilities
# Format code before committing
dotnet format
# Check formatting without changing files
dotnet format --verify-no-changes- PascalCase: Classes, methods, properties, events
- camelCase: Local variables, parameters
- _camelCase: Private fields
- UPPER_CASE: Constants
- One class per file
- File name matches class name
- Use file-scoped namespaces (C# 10+)
- Order members: fields, constructors, properties, methods
namespace AdvancedConcepts.Advanced;
public class ExamplePattern
{
// Private fields
private readonly IService _service;
private readonly ILogger<ExamplePattern> _logger;
// Constructor
public ExamplePattern(IService service, ILogger<ExamplePattern> logger)
{
_service = service ?? throw new ArgumentNullException(nameof(service));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
// Public properties
public string Name { get; init; }
// Public methods
public async Task<Result<Data>> ProcessAsync(int id)
{
_logger.LogInformation("Processing {Id}", id);
try
{
var data = await _service.GetDataAsync(id);
return Result.Success(data);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to process {Id}", id);
return Result.Failure<Data>(new ProcessingError(ex.Message));
}
}
// Private methods
private void ValidateData(Data data)
{
// Validation logic
}
}- Use xUnit framework
- Use FluentAssertions for assertions
- Use Moq or NSubstitute for mocking
- Use AutoFixture for test data generation
public class ExamplePatternTests
{
private readonly Mock<IService> _serviceMock;
private readonly ExamplePattern _sut;
public ExamplePatternTests()
{
_serviceMock = new Mock<IService>();
_sut = new ExamplePattern(_serviceMock.Object, Mock.Of<ILogger<ExamplePattern>>());
}
[Fact]
public async Task ProcessAsync_WhenSuccessful_ReturnsSuccess()
{
// Arrange
var expected = new Data { Id = 1, Name = "Test" };
_serviceMock.Setup(s => s.GetDataAsync(1)).ReturnsAsync(expected);
// Act
var result = await _sut.ProcessAsync(1);
// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().BeEquivalentTo(expected);
}
}- Aim for >90% code coverage for new code
- Use
dotnet test --collect:"XPlat Code Coverage" - View coverage reports in
coverage/directory
- Use FsCheck for property-based tests
- Test invariants and properties
- Let FsCheck generate test cases
[Property]
public Property ReverseTwice_ReturnsOriginal(int[] array)
{
var result = array.Reverse().Reverse();
return result.SequenceEqual(array).ToProperty();
}-
Update from upstream:
git fetch upstream git rebase upstream/master
-
Ensure all checks pass:
dotnet build dotnet test dotnet format --verify-no-changes -
Run security checks (if pre-commit installed):
pre-commit run --all-files
-
Update documentation if needed
-
Create feature branch:
git checkout -b feature/your-feature-name
-
Commit with conventional commits:
git commit -m "feat: add covariance example for IEnumerable" git commit -m "fix: resolve null reference in boxing example" git commit -m "docs: update CONTRIBUTING.md with testing guidelines"
Commit types: feat, fix, docs, style, refactor, perf, test, chore
-
Push to your fork:
git push origin feature/your-feature-name
-
Open Pull Request on GitHub
- ✅ Descriptive title using conventional commits format
- ✅ Description explaining what and why
- ✅ Link related issues (Fixes #123)
- ✅ All CI checks passing
- ✅ Tests added/updated
- ✅ Documentation updated
- ✅ Code reviewed by at least one maintainer
- Automated checks run (build, test, security)
- Code review by maintainers
- Requested changes addressed
- Approval from maintainer
- Squash and merge to main branch
- Add XML documentation comments for public APIs
- Include
<summary>,<param>,<returns>,<example> - Document complex algorithms or non-obvious logic
/// <summary>
/// Processes the order asynchronously with retry logic.
/// </summary>
/// <param name="orderId">The unique identifier of the order to process.</param>
/// <returns>A result containing the processed order or an error.</returns>
/// <example>
/// <code>
/// var result = await ProcessOrderAsync(123);
/// if (result.IsSuccess)
/// {
/// Console.WriteLine($"Order processed: {result.Value.Id}");
/// }
/// </code>
/// </example>
public async Task<Result<Order>> ProcessOrderAsync(int orderId)
{
// Implementation
}- Use clear headings and structure
- Include code examples where helpful
- Add diagrams using Mermaid when appropriate
- Keep line length under 120 characters
Contributors will be recognized in:
- Contributors section of README
- Release notes for their contributions
- GitHub contributors page
- Discussions: Use GitHub Discussions
- Issues: Search existing issues or create new one
- Email: dogaaydinn@gmail.com for private inquiries
Thank you for contributing to Advanced C# Concepts! 🚀
Last Updated: 2025-11-30 Version: 1.0