https://github.com/paulnonatomic/servicekitanalyzers
https://github.com/paulnonatomic/servicekitanalyzers
Last synced: 7 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/paulnonatomic/servicekitanalyzers
- Owner: PaulNonatomic
- Created: 2025-08-11T23:00:44.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-08-12T10:00:09.000Z (10 months ago)
- Last Synced: 2025-08-12T11:42:23.237Z (10 months ago)
- Language: C#
- Size: 11.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ServiceKit.Analyzers
Roslyn analyzers and code fixers to enforce ServiceKit best practices in Unity projects. These analyzers help developers write better, more maintainable code when using ServiceKit's dependency injection framework.
## Overview
ServiceKit.Analyzers provides compile-time validation of dependency injection patterns, ensuring:
- Proper interface-based injection for better testability and AOT compatibility
- Correct field visibility and modifiers for injected services
- Proper cancellation token usage in async injection chains
- Consistent coding patterns across your ServiceKit implementation
## Analyzers and Code Fixers
### SK001: Injected Member Must Be Interface
**Severity:** Warning
**Category:** ServiceKit.Usage
#### Description
Enforces that members decorated with `[InjectService]` attribute should be interface types rather than concrete classes. This promotes loose coupling, better testability, and AOT-friendly code.
#### Example
```csharp
// ❌ Bad - Using concrete class
[InjectService] private MyService _service;
// ✅ Good - Using interface
[InjectService] private IMyService _service;
```
#### Code Fixer
The code fixer automatically suggests all interfaces implemented by the concrete type, allowing you to quickly change the member type to an appropriate interface.
---
### SK002: Injected Field Visibility
**Severity:** Warning
**Category:** ServiceKit.Usage
#### Description
Ensures that fields with `[InjectService]` attribute follow ServiceKit's requirements:
- Must be `private` (to avoid Unity inspector exposure)
- Must be instance fields (not `static`)
- Must be mutable (not `readonly`)
- Must not have `[SerializeField]` attribute
#### Example
```csharp
// ❌ Bad - Public, static, readonly, or serialized
[InjectService] public IMyService Service;
[InjectService] static IMyService _service;
[InjectService] readonly IMyService _service;
[SerializeField][InjectService] private IMyService _service;
// ✅ Good - Private, instance, mutable field
[InjectService] private IMyService _service;
```
#### Code Fixer
Automatically corrects field modifiers to make them private, instance, mutable, and removes any `[SerializeField]` attributes.
---
### SK004: Injection Must Include Cancellation
**Severity:** Warning
**Category:** ServiceKit.Async
#### Description
Ensures that async injection chains specify a destroy cancellation token to properly handle Unity object lifecycle. This prevents memory leaks and ensures clean shutdown when GameObjects are destroyed.
#### Example
```csharp
// ❌ Bad - Missing cancellation token
await _locator.InjectServicesAsync(gameObject)
.ExecuteAsync();
// ✅ Good - With cancellation token
await _locator.InjectServicesAsync(gameObject)
.WithCancellation(destroyCancellationToken)
.ExecuteAsync();
// ✅ Also good - Using convenience method
await _locator.InjectServicesAsync(gameObject)
.ExecuteWithCancellationAsync(destroyCancellationToken);
```
#### Code Fixer
Offers two fixes:
1. Add `.WithCancellation(destroyCancellationToken)` to the chain
2. Replace `.ExecuteAsync()` with `.ExecuteWithCancellationAsync(destroyCancellationToken)`
---
### SK010: Prefer ExecuteWithCancellationAsync
**Severity:** Info
**Category:** ServiceKit.Async
#### Description
Suggests using the convenience method `ExecuteWithCancellationAsync` instead of the longer `.WithCancellation().ExecuteAsync()` pattern for cleaner, more consistent code.
#### Example
```csharp
// ⚠️ Works but verbose
await _locator.InjectServicesAsync(gameObject)
.WithCancellation(destroyCancellationToken)
.ExecuteAsync();
// ✅ Preferred - Cleaner syntax
await _locator.InjectServicesAsync(gameObject)
.ExecuteWithCancellationAsync(destroyCancellationToken);
```
#### Code Fixer
Automatically refactors the code to use the convenience method, removing the `.WithCancellation()` call and replacing `.ExecuteAsync()` with `.ExecuteWithCancellationAsync()`.
## Building ServiceKit.Analyzers
### Development Build
For local development and testing:
```
dotnet build
```
Output: `bin/Debug/netstandard2.0/ServiceKit.Analyzers.dll`
### Release Build
For production release:
```
dotnet build -c Release
```
Output: `bin/Release/netstandard2.0/ServiceKit.Analyzers.dll`
### Copy to Output Directory
To copy the analyzer DLL to a specific output directory:
```
dotnet build -c Release -o
```
The analyzer DLL can then be referenced by projects that need ServiceKit analysis.
## Integration with ServiceKit
These analyzers are designed to work seamlessly with ServiceKit's dependency injection system in Unity. They help enforce best practices such as:
- **Interface-based injection:** Promotes testability and allows for easy mocking/substitution
- **Proper field configuration:** Ensures injected fields work correctly with ServiceKit's injection mechanism
- **Lifecycle management:** Ensures proper cancellation token usage to prevent memory leaks
- **Code consistency:** Promotes use of standardized patterns across your codebase
## Technical Details
- **Target Framework:** .NET Standard 2.0 for broad compatibility
- **Language Version:** Latest C# with nullable reference types enabled
- **Dependencies:** Microsoft.CodeAnalysis.CSharp 4.10.0
- **Package Type:** Development dependency (no runtime impact)