@el-j/magic-helix-plugins 4.0.0-beta.2 → 4.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/architecture/codeowners.md +123 -0
  2. package/dist/architecture/monorepo.md +146 -0
  3. package/dist/architecture/nx.md +122 -0
  4. package/dist/architecture/turborepo.md +114 -0
  5. package/dist/ci/github-actions.md +268 -0
  6. package/dist/ci/gitlab-ci.md +330 -0
  7. package/dist/containers/docker-multistage.md +120 -0
  8. package/dist/containers/kubernetes-deploy.md +210 -0
  9. package/dist/cpp/index.cjs +79 -0
  10. package/dist/cpp/index.mjs +209 -0
  11. package/dist/csharp/index.cjs +2 -2
  12. package/dist/csharp/{index.js → index.mjs} +17 -11
  13. package/dist/csharp/templates/framework-aspnetcore.md +205 -0
  14. package/dist/csharp/templates/framework-blazor.md +271 -0
  15. package/dist/csharp/templates/lang-csharp.md +162 -0
  16. package/dist/devops/docker-compose.md +111 -0
  17. package/dist/devops/docker-dockerfile.md +94 -0
  18. package/dist/devops/github-actions.md +160 -0
  19. package/dist/devops/gitlab-ci.md +210 -0
  20. package/dist/generic/lang-typescript.md +57 -0
  21. package/dist/generic/state-redux.md +21 -0
  22. package/dist/generic/state-rxjs.md +6 -0
  23. package/dist/generic/style-mui.md +23 -0
  24. package/dist/generic/style-tailwind.md +76 -0
  25. package/dist/generic/test-cypress.md +21 -0
  26. package/dist/generic/test-jest.md +20 -0
  27. package/dist/generic/test-playwright.md +21 -0
  28. package/dist/generic/test-vitest.md +131 -0
  29. package/dist/go/index.cjs +3 -3
  30. package/dist/go/{index.js → index.mjs} +18 -15
  31. package/dist/go/templates/lang-go.md +571 -0
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.mjs +24 -0
  34. package/dist/java/index.cjs +2 -2
  35. package/dist/java/{index.js → index.mjs} +25 -19
  36. package/dist/java/templates/build-gradle.md +102 -0
  37. package/dist/java/templates/build-maven.md +86 -0
  38. package/dist/java/templates/framework-spring-boot.md +179 -0
  39. package/dist/java/templates/lang-java.md +78 -0
  40. package/dist/java/templates/lang-kotlin.md +88 -0
  41. package/dist/meta/magic-helix-meta.md +213 -0
  42. package/dist/meta/meta-debug.md +459 -0
  43. package/dist/meta/meta-implement.md +450 -0
  44. package/dist/meta/meta-roadmap.md +265 -0
  45. package/dist/nodejs/templates/angular-core.md +19 -0
  46. package/dist/nodejs/templates/lang-typescript.md +57 -0
  47. package/dist/nodejs/templates/nestjs-core.md +7 -0
  48. package/dist/nodejs/templates/react-core.md +677 -0
  49. package/dist/nodejs/templates/react-zustand.md +7 -0
  50. package/dist/nodejs/templates/state-redux.md +21 -0
  51. package/dist/nodejs/templates/state-rxjs.md +6 -0
  52. package/dist/nodejs/templates/style-primevue.md +6 -0
  53. package/dist/nodejs/templates/style-quasar.md +22 -0
  54. package/dist/nodejs/templates/style-tailwind.md +76 -0
  55. package/dist/nodejs/templates/test-cypress.md +21 -0
  56. package/dist/nodejs/templates/test-jest.md +20 -0
  57. package/dist/nodejs/templates/test-playwright.md +21 -0
  58. package/dist/nodejs/templates/test-vitest.md +131 -0
  59. package/dist/nodejs/templates/vue-core.md +108 -0
  60. package/dist/nodejs/templates/vue-pinia.md +5 -0
  61. package/dist/patterns/architecture/clean-architecture.md +469 -0
  62. package/dist/patterns/architecture/dependency-injection.md +517 -0
  63. package/dist/patterns/architecture/domain-driven-design.md +621 -0
  64. package/dist/patterns/architecture/layered-architecture.md +382 -0
  65. package/dist/patterns/architecture/repository-pattern.md +408 -0
  66. package/dist/patterns/domain-expertise/nextjs-rules.md +115 -0
  67. package/dist/patterns/domain-expertise/react-patterns.md +181 -0
  68. package/dist/patterns/domain-expertise/server-components.md +212 -0
  69. package/dist/patterns/domain-expertise/shadcn-ui.md +52 -0
  70. package/dist/patterns/domain-expertise/tailwind-patterns.md +52 -0
  71. package/dist/patterns/environment/container-awareness.md +17 -0
  72. package/dist/patterns/environment/ide-features.md +17 -0
  73. package/dist/patterns/environment/os-commands.md +17 -0
  74. package/dist/patterns/organization/heading-hierarchy.md +103 -0
  75. package/dist/patterns/organization/sequential-workflows.md +102 -0
  76. package/dist/patterns/organization/xml-rule-groups.md +64 -0
  77. package/dist/patterns/reasoning/agent-loop.md +151 -0
  78. package/dist/patterns/reasoning/confirmation-gates.md +141 -0
  79. package/dist/patterns/reasoning/dependency-analysis.md +132 -0
  80. package/dist/patterns/reasoning/one-tool-per-iteration.md +152 -0
  81. package/dist/patterns/reasoning/preview-before-action.md +194 -0
  82. package/dist/patterns/reasoning/reflection-checkpoints.md +166 -0
  83. package/dist/patterns/reasoning/result-verification.md +157 -0
  84. package/dist/patterns/reasoning/subtask-breakdown.md +131 -0
  85. package/dist/patterns/reasoning/thinking-tags.md +100 -0
  86. package/dist/patterns/role-definition/capability-declarations.md +72 -0
  87. package/dist/patterns/role-definition/expert-identity.md +45 -0
  88. package/dist/patterns/role-definition/scope-boundaries.md +61 -0
  89. package/dist/patterns/safety/code-safety-rules.md +17 -0
  90. package/dist/patterns/safety/credential-handling.md +17 -0
  91. package/dist/patterns/safety/destructive-warnings.md +17 -0
  92. package/dist/patterns/safety/refusal-messages.md +17 -0
  93. package/dist/patterns/tone/adaptive-tone.md +17 -0
  94. package/dist/patterns/tone/concise-communication.md +17 -0
  95. package/dist/patterns/tone/forbidden-phrases.md +17 -0
  96. package/dist/patterns/tool-guidelines/function-schemas.md +143 -0
  97. package/dist/patterns/tool-guidelines/parameter-examples.md +137 -0
  98. package/dist/patterns/tool-guidelines/usage-policies.md +105 -0
  99. package/dist/php/index.cjs +2 -2
  100. package/dist/php/{index.js → index.mjs} +12 -6
  101. package/dist/php/templates/framework-laravel.md +112 -0
  102. package/dist/php/templates/lang-php.md +94 -0
  103. package/dist/python/index.cjs +4 -4
  104. package/dist/python/{index.js → index.mjs} +10 -7
  105. package/dist/python/templates/lang-python.md +508 -0
  106. package/dist/ruby/index.cjs +2 -2
  107. package/dist/ruby/{index.js → index.mjs} +16 -10
  108. package/dist/ruby/templates/framework-rails.md +309 -0
  109. package/dist/ruby/templates/framework-sinatra.md +227 -0
  110. package/dist/ruby/templates/lang-ruby.md +216 -0
  111. package/dist/rust/index.cjs +3 -3
  112. package/dist/rust/{index.js → index.mjs} +24 -18
  113. package/dist/rust/templates/lang-rust.md +89 -0
  114. package/dist/swift/index.cjs +32 -0
  115. package/dist/swift/index.mjs +112 -0
  116. package/dist/swift/templates/framework-vapor.md +352 -0
  117. package/dist/swift/templates/lang-swift.md +291 -0
  118. package/package.json +31 -21
  119. package/dist/index.js +0 -20
  120. /package/dist/nodejs/{index.js → index.mjs} +0 -0
@@ -0,0 +1,205 @@
1
+ # ASP.NET Core Framework Instructions
2
+
3
+ ## Architecture
4
+
5
+ ### Minimal API (Modern)
6
+ ```csharp
7
+ var builder = WebApplication.CreateBuilder(args);
8
+ builder.Services.AddEndpointsApiExplorer();
9
+ builder.Services.AddSwaggerGen();
10
+
11
+ var app = builder.Build();
12
+
13
+ app.MapGet("/api/users/{id}", async (int id, UserService service) => {
14
+ var user = await service.GetUserAsync(id);
15
+ return user is not null ? Results.Ok(user) : Results.NotFound();
16
+ });
17
+
18
+ app.Run();
19
+ ```
20
+
21
+ ### Controller-based API
22
+ ```csharp
23
+ [ApiController]
24
+ [Route("api/[controller]")]
25
+ public class UsersController : ControllerBase {
26
+ private readonly UserService _service;
27
+
28
+ public UsersController(UserService service) => _service = service;
29
+
30
+ [HttpGet("{id}")]
31
+ public async Task<ActionResult<User>> GetUser(int id) {
32
+ var user = await _service.GetUserAsync(id);
33
+ return user is not null ? Ok(user) : NotFound();
34
+ }
35
+
36
+ [HttpPost]
37
+ public async Task<ActionResult<User>> CreateUser(CreateUserRequest request) {
38
+ var user = await _service.CreateUserAsync(request);
39
+ return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
40
+ }
41
+ }
42
+ ```
43
+
44
+ ## Dependency Injection
45
+
46
+ ```csharp
47
+ // Program.cs
48
+ builder.Services.AddDbContext<AppDbContext>(options =>
49
+ options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
50
+
51
+ builder.Services.AddScoped<IUserRepository, UserRepository>();
52
+ builder.Services.AddScoped<UserService>();
53
+ builder.Services.AddSingleton<ICacheService, RedisCacheService>();
54
+ ```
55
+
56
+ ## Entity Framework Core
57
+
58
+ ### DbContext
59
+ ```csharp
60
+ public class AppDbContext : DbContext {
61
+ public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
62
+
63
+ public DbSet<User> Users => Set<User>();
64
+ public DbSet<Order> Orders => Set<Order>();
65
+
66
+ protected override void OnModelCreating(ModelBuilder modelBuilder) {
67
+ modelBuilder.Entity<User>(entity => {
68
+ entity.HasKey(e => e.Id);
69
+ entity.HasIndex(e => e.Email).IsUnique();
70
+ entity.Property(e => e.Name).HasMaxLength(100).IsRequired();
71
+ });
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### Migrations
77
+ ```bash
78
+ dotnet ef migrations add InitialCreate
79
+ dotnet ef database update
80
+ dotnet ef migrations remove
81
+ ```
82
+
83
+ ## Configuration
84
+
85
+ ### appsettings.json
86
+ ```json
87
+ {
88
+ "ConnectionStrings": {
89
+ "DefaultConnection": "Server=localhost;Database=myapp;User Id=sa;Password=P@ssw0rd;"
90
+ },
91
+ "Logging": {
92
+ "LogLevel": {
93
+ "Default": "Information",
94
+ "Microsoft.AspNetCore": "Warning"
95
+ }
96
+ },
97
+ "JwtSettings": {
98
+ "Secret": "${JWT_SECRET}",
99
+ "ExpirationMinutes": 60
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Options Pattern
105
+ ```csharp
106
+ public class JwtSettings {
107
+ public string Secret { get; set; } = string.Empty;
108
+ public int ExpirationMinutes { get; set; }
109
+ }
110
+
111
+ // Register
112
+ builder.Services.Configure<JwtSettings>(
113
+ builder.Configuration.GetSection("JwtSettings"));
114
+
115
+ // Use
116
+ public class AuthService {
117
+ private readonly JwtSettings _settings;
118
+
119
+ public AuthService(IOptions<JwtSettings> options) {
120
+ _settings = options.Value;
121
+ }
122
+ }
123
+ ```
124
+
125
+ ## Middleware
126
+
127
+ ```csharp
128
+ public class RequestLoggingMiddleware {
129
+ private readonly RequestDelegate _next;
130
+ private readonly ILogger<RequestLoggingMiddleware> _logger;
131
+
132
+ public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger) {
133
+ _next = next;
134
+ _logger = logger;
135
+ }
136
+
137
+ public async Task InvokeAsync(HttpContext context) {
138
+ _logger.LogInformation("Request: {Method} {Path}", context.Request.Method, context.Request.Path);
139
+ await _next(context);
140
+ }
141
+ }
142
+
143
+ // Register
144
+ app.UseMiddleware<RequestLoggingMiddleware>();
145
+ ```
146
+
147
+ ## Authentication & Authorization
148
+
149
+ ```csharp
150
+ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
151
+ .AddJwtBearer(options => {
152
+ options.TokenValidationParameters = new TokenValidationParameters {
153
+ ValidateIssuer = true,
154
+ ValidateAudience = true,
155
+ ValidateLifetime = true,
156
+ ValidateIssuerSigningKey = true,
157
+ ValidIssuer = builder.Configuration["Jwt:Issuer"],
158
+ ValidAudience = builder.Configuration["Jwt:Audience"],
159
+ IssuerSigningKey = new SymmetricSecurityKey(
160
+ Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
161
+ };
162
+ });
163
+
164
+ builder.Services.AddAuthorization(options => {
165
+ options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
166
+ });
167
+ ```
168
+
169
+ ## Health Checks
170
+
171
+ ```csharp
172
+ builder.Services.AddHealthChecks()
173
+ .AddNpgSql(builder.Configuration.GetConnectionString("DefaultConnection")!)
174
+ .AddRedis(builder.Configuration.GetConnectionString("Redis")!);
175
+
176
+ app.MapHealthChecks("/health");
177
+ ```
178
+
179
+ ## Docker Production Setup
180
+
181
+ ```dockerfile
182
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
183
+ WORKDIR /app
184
+ COPY --from=build /app/publish .
185
+
186
+ ENV ASPNETCORE_URLS=http://+:8080
187
+ ENV ASPNETCORE_ENVIRONMENT=Production
188
+
189
+ EXPOSE 8080
190
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
191
+ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
192
+
193
+ ENTRYPOINT ["dotnet", "MyApp.dll"]
194
+ ```
195
+
196
+ ## Performance Best Practices
197
+
198
+ - Use async/await throughout
199
+ - Enable response compression
200
+ - Implement caching (ResponseCache, MemoryCache, Redis)
201
+ - Use connection pooling for databases
202
+ - Minimize allocations in hot paths
203
+ - Use `Span<T>` for high-performance scenarios
204
+ - Enable HTTP/2 and HTTP/3
205
+ - Use output caching (ASP.NET Core 7+)
@@ -0,0 +1,271 @@
1
+ # Blazor Framework Instructions
2
+
3
+ ## Blazor Modes
4
+
5
+ ### Blazor WebAssembly (Client-side)
6
+ - Runs in browser via WebAssembly
7
+ - Full .NET runtime in browser
8
+ - Offline capable after initial load
9
+ - Slower initial load time
10
+
11
+ ### Blazor Server (Server-side)
12
+ - UI updates via SignalR connection
13
+ - Fast initial load
14
+ - Less client resources needed
15
+ - Requires persistent connection
16
+
17
+ ### Blazor Hybrid (.NET MAUI)
18
+ - Native desktop/mobile apps
19
+ - Uses platform WebView
20
+ - Full .NET access
21
+
22
+ ## Component Structure
23
+
24
+ ### Basic Component
25
+ ```razor
26
+ @page "/users"
27
+ @inject UserService UserService
28
+
29
+ <h3>Users</h3>
30
+
31
+ @if (users == null) {
32
+ <p>Loading...</p>
33
+ } else {
34
+ <ul>
35
+ @foreach (var user in users) {
36
+ <li>@user.Name - @user.Email</li>
37
+ }
38
+ </ul>
39
+ }
40
+
41
+ @code {
42
+ private List<User>? users;
43
+
44
+ protected override async Task OnInitializedAsync() {
45
+ users = await UserService.GetUsersAsync();
46
+ }
47
+ }
48
+ ```
49
+
50
+ ### Component with Parameters
51
+ ```razor
52
+ @* UserCard.razor *@
53
+ <div class="card">
54
+ <h4>@User.Name</h4>
55
+ <p>@User.Email</p>
56
+ <button @onclick="OnDeleteClick">Delete</button>
57
+ </div>
58
+
59
+ @code {
60
+ [Parameter]
61
+ public User User { get; set; } = null!;
62
+
63
+ [Parameter]
64
+ public EventCallback<User> OnDelete { get; set; }
65
+
66
+ private async Task OnDeleteClick() {
67
+ await OnDelete.InvokeAsync(User);
68
+ }
69
+ }
70
+ ```
71
+
72
+ ## Data Binding
73
+
74
+ ### Two-way Binding
75
+ ```razor
76
+ <input @bind="username" />
77
+ <input @bind="username" @bind:event="oninput" />
78
+
79
+ @code {
80
+ private string username = "";
81
+ }
82
+ ```
83
+
84
+ ### Form Validation
85
+ ```razor
86
+ <EditForm Model="user" OnValidSubmit="HandleSubmit">
87
+ <DataAnnotationsValidator />
88
+ <ValidationSummary />
89
+
90
+ <InputText @bind-Value="user.Name" />
91
+ <ValidationMessage For="@(() => user.Name)" />
92
+
93
+ <InputText @bind-Value="user.Email" type="email" />
94
+ <ValidationMessage For="@(() => user.Email)" />
95
+
96
+ <button type="submit">Submit</button>
97
+ </EditForm>
98
+
99
+ @code {
100
+ private UserDto user = new();
101
+
102
+ private async Task HandleSubmit() {
103
+ await UserService.CreateUserAsync(user);
104
+ }
105
+ }
106
+
107
+ public class UserDto {
108
+ [Required]
109
+ [StringLength(100)]
110
+ public string Name { get; set; } = "";
111
+
112
+ [Required]
113
+ [EmailAddress]
114
+ public string Email { get; set; } = "";
115
+ }
116
+ ```
117
+
118
+ ## Dependency Injection
119
+
120
+ ```csharp
121
+ // Program.cs (Blazor WebAssembly)
122
+ builder.Services.AddScoped<UserService>();
123
+ builder.Services.AddScoped(sp => new HttpClient {
124
+ BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
125
+ });
126
+
127
+ // Program.cs (Blazor Server)
128
+ builder.Services.AddScoped<UserService>();
129
+ builder.Services.AddDbContext<AppDbContext>(options =>
130
+ options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
131
+ ```
132
+
133
+ ## JavaScript Interop
134
+
135
+ ```razor
136
+ @inject IJSRuntime JS
137
+
138
+ <button @onclick="ShowAlert">Show Alert</button>
139
+
140
+ @code {
141
+ private async Task ShowAlert() {
142
+ await JS.InvokeVoidAsync("alert", "Hello from Blazor!");
143
+ }
144
+ }
145
+ ```
146
+
147
+ ```javascript
148
+ // wwwroot/js/app.js
149
+ window.blazorHelpers = {
150
+ focusElement: (elementId) => {
151
+ document.getElementById(elementId)?.focus();
152
+ }
153
+ };
154
+ ```
155
+
156
+ ```csharp
157
+ await JS.InvokeVoidAsync("blazorHelpers.focusElement", "myInput");
158
+ ```
159
+
160
+ ## State Management
161
+
162
+ ### Cascading Parameters
163
+ ```razor
164
+ <CascadingValue Value="theme">
165
+ <ChildComponent />
166
+ </CascadingValue>
167
+
168
+ @code {
169
+ private string theme = "dark";
170
+ }
171
+
172
+ // In child component
173
+ @code {
174
+ [CascadingParameter]
175
+ public string Theme { get; set; } = "";
176
+ }
177
+ ```
178
+
179
+ ### Scoped Service for State
180
+ ```csharp
181
+ public class AppState {
182
+ public event Action? OnChange;
183
+ private string? _currentUser;
184
+
185
+ public string? CurrentUser {
186
+ get => _currentUser;
187
+ set {
188
+ _currentUser = value;
189
+ NotifyStateChanged();
190
+ }
191
+ }
192
+
193
+ private void NotifyStateChanged() => OnChange?.Invoke();
194
+ }
195
+
196
+ // Register as scoped
197
+ builder.Services.AddScoped<AppState>();
198
+
199
+ // Use in component
200
+ @implements IDisposable
201
+ @inject AppState AppState
202
+
203
+ @code {
204
+ protected override void OnInitialized() {
205
+ AppState.OnChange += StateHasChanged;
206
+ }
207
+
208
+ public void Dispose() {
209
+ AppState.OnChange -= StateHasChanged;
210
+ }
211
+ }
212
+ ```
213
+
214
+ ## Performance Optimization
215
+
216
+ ### Virtualization
217
+ ```razor
218
+ <Virtualize Items="@users" Context="user">
219
+ <UserCard User="user" />
220
+ </Virtualize>
221
+ ```
222
+
223
+ ### Lazy Loading
224
+ ```razor
225
+ @page "/admin"
226
+ @attribute [Authorize(Roles = "Admin")]
227
+
228
+ <h3>Admin Panel</h3>
229
+ ```
230
+
231
+ ```csharp
232
+ // Program.cs
233
+ builder.Services.AddScoped<LazyAssemblyLoader>();
234
+
235
+ // Load assemblies on demand
236
+ await LazyAssemblyLoader.LoadAssembliesAsync(new[] { "AdminModule.dll" });
237
+ ```
238
+
239
+ ## Docker Deployment
240
+
241
+ ### Blazor WebAssembly
242
+ ```dockerfile
243
+ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
244
+ WORKDIR /src
245
+ COPY . .
246
+ RUN dotnet publish -c Release -o /app/publish
247
+
248
+ FROM nginx:alpine
249
+ COPY --from=build /app/publish/wwwroot /usr/share/nginx/html
250
+ COPY nginx.conf /etc/nginx/nginx.conf
251
+ ```
252
+
253
+ ### Blazor Server
254
+ ```dockerfile
255
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
256
+ WORKDIR /app
257
+ COPY --from=build /app/publish .
258
+ EXPOSE 8080
259
+ ENTRYPOINT ["dotnet", "BlazorApp.dll"]
260
+ ```
261
+
262
+ ## Best Practices
263
+
264
+ - Use `@key` for list items to improve rendering performance
265
+ - Avoid unnecessary re-renders with `ShouldRender()`
266
+ - Use `StateHasChanged()` sparingly
267
+ - Implement proper error boundaries
268
+ - Use streaming rendering for improved perceived performance
269
+ - Minimize JS interop calls
270
+ - Use virtual scrolling for large lists
271
+ - Implement proper loading states
@@ -0,0 +1,162 @@
1
+ # C# / .NET Instructions
2
+
3
+ ## Project Type
4
+ - Language: C#
5
+ - Framework: {.NET 6|.NET 7|.NET 8}
6
+ - App Type: {ASP.NET Core|Console|Library|Blazor|MAUI}
7
+
8
+ ## Build Commands
9
+
10
+ ```bash
11
+ dotnet restore # Restore NuGet packages
12
+ dotnet build # Build project
13
+ dotnet test # Run tests
14
+ dotnet run # Run application
15
+ dotnet publish -c Release # Publish for deployment
16
+ ```
17
+
18
+ ## Code Conventions
19
+
20
+ ### C# Modern Features
21
+ ```csharp
22
+ // Nullable reference types (C# 8+)
23
+ #nullable enable
24
+ public class User {
25
+ public string Name { get; set; } = string.Empty;
26
+ public string? Email { get; set; }
27
+ }
28
+
29
+ // Records (C# 9+)
30
+ public record Product(int Id, string Name, decimal Price);
31
+
32
+ // Pattern matching (C# 9+)
33
+ var result = value switch {
34
+ null => "null",
35
+ > 0 => "positive",
36
+ < 0 => "negative",
37
+ _ => "zero"
38
+ };
39
+ ```
40
+
41
+ ### Async/Await
42
+ ```csharp
43
+ public async Task<User> GetUserAsync(int id) {
44
+ var user = await _context.Users.FindAsync(id);
45
+ return user ?? throw new NotFoundException();
46
+ }
47
+ ```
48
+
49
+ ### LINQ
50
+ ```csharp
51
+ var activeUsers = users
52
+ .Where(u => u.IsActive)
53
+ .OrderBy(u => u.Name)
54
+ .Select(u => new UserDto(u.Id, u.Name));
55
+ ```
56
+
57
+ ## Docker Optimization
58
+
59
+ ### Multi-stage Dockerfile
60
+ ```dockerfile
61
+ # Build stage
62
+ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
63
+ WORKDIR /src
64
+ COPY ["MyApp.csproj", "./"]
65
+ RUN dotnet restore
66
+ COPY . .
67
+ RUN dotnet publish -c Release -o /app/publish
68
+
69
+ # Runtime stage
70
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
71
+ WORKDIR /app
72
+ COPY --from=build /app/publish .
73
+
74
+ # Non-root user
75
+ RUN adduser -u 1000 -D appuser && chown -R appuser /app
76
+ USER appuser
77
+
78
+ EXPOSE 8080
79
+ ENTRYPOINT ["dotnet", "MyApp.dll"]
80
+ ```
81
+
82
+ ### Docker Compose for Development
83
+ ```yaml
84
+ services:
85
+ app:
86
+ build: .
87
+ ports:
88
+ - "8080:8080"
89
+ environment:
90
+ - ASPNETCORE_ENVIRONMENT=Development
91
+ - ConnectionStrings__DefaultConnection=Server=db;Database=mydb;
92
+ depends_on:
93
+ - db
94
+
95
+ db:
96
+ image: postgres:15-alpine
97
+ environment:
98
+ POSTGRES_PASSWORD: devpassword
99
+ ```
100
+
101
+ ## Testing
102
+
103
+ ### Unit Tests (xUnit)
104
+ ```csharp
105
+ public class UserServiceTests {
106
+ [Fact]
107
+ public async Task GetUser_ReturnsUser_WhenExists() {
108
+ // Arrange
109
+ var service = new UserService(mockRepo);
110
+
111
+ // Act
112
+ var result = await service.GetUserAsync(1);
113
+
114
+ // Assert
115
+ Assert.NotNull(result);
116
+ Assert.Equal("John", result.Name);
117
+ }
118
+ }
119
+ ```
120
+
121
+ ### Integration Tests
122
+ ```csharp
123
+ public class ApiTests : IClassFixture<WebApplicationFactory<Program>> {
124
+ private readonly HttpClient _client;
125
+
126
+ public ApiTests(WebApplicationFactory<Program> factory) {
127
+ _client = factory.CreateClient();
128
+ }
129
+
130
+ [Fact]
131
+ public async Task GetUser_ReturnsOk() {
132
+ var response = await _client.GetAsync("/api/users/1");
133
+ response.EnsureSuccessStatusCode();
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## NuGet Package Management
139
+
140
+ ```bash
141
+ dotnet add package Microsoft.EntityFrameworkCore
142
+ dotnet remove package OldPackage
143
+ dotnet list package --outdated
144
+ ```
145
+
146
+ ## Performance Tips
147
+
148
+ - Use `Span<T>` and `Memory<T>` for high-performance scenarios
149
+ - Enable nullable reference types for better null safety
150
+ - Use `ValueTask` for frequently synchronous operations
151
+ - Leverage record types for immutable DTOs
152
+ - Use source generators to reduce reflection overhead
153
+ - Profile with dotnet-trace and dotnet-counters
154
+
155
+ ## Security
156
+
157
+ - Enable nullable reference types
158
+ - Use `IOptions<T>` for configuration
159
+ - Implement proper authentication/authorization
160
+ - Validate user input
161
+ - Use parameterized queries (EF Core does this)
162
+ - Keep dependencies updated