Skip to content

Commit 68c061e

Browse files
authored
Update README.md
1 parent 3df918f commit 68c061e

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

README.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,179 @@
11
# SimpleInjection
2+
3+
A lightweight dependency injection library for C# that combines simple DI container functionality with powerful source generation for content management.
4+
5+
## Features
6+
7+
### 🚀 Simple Dependency Injection
8+
- **Attribute-based registration** - Mark classes with `[Singleton]`, `[Scoped]`, or `[Transient]`
9+
- **Automatic service discovery** - No manual registration required
10+
- **Constructor injection** - Automatic dependency resolution
11+
- **Scope management** - Built-in scoped service lifetime management
12+
13+
### ⚡ Content Source Generation
14+
- **Automatic enum generation** - Creates enums from your content collections
15+
- **Type-safe access** - Generated helper methods for accessing content by enum or index
16+
- **Performance optimized** - Uses `NamedComparer<T>` for fast dictionary lookups
17+
- **Roslyn analyzers** - Enforces best practices and catches common mistakes
18+
19+
## Quick Start
20+
21+
### 1. Install the Package
22+
```bash
23+
dotnet add package SimpleInjection
24+
```
25+
26+
### 2. Dependency Injection Usage
27+
28+
Mark your classes with lifetime attributes:
29+
30+
```csharp
31+
[Singleton]
32+
public class DatabaseService
33+
{
34+
public void Connect() => Console.WriteLine("Connected to database");
35+
}
36+
37+
[Scoped]
38+
public class UserService
39+
{
40+
private readonly DatabaseService _database;
41+
42+
public UserService(DatabaseService database)
43+
{
44+
_database = database;
45+
}
46+
47+
public void GetUser() => _database.Connect();
48+
}
49+
```
50+
51+
Initialize and use the host:
52+
53+
```csharp
54+
var host = Host.Initialize();
55+
56+
// Get singleton services directly
57+
var dbService = host.Get<DatabaseService>();
58+
59+
// Create scopes for scoped services
60+
using var scope = host.CreateScope();
61+
var userService = scope.Get<UserService>();
62+
```
63+
64+
### 3. Content Generation Usage
65+
66+
Define your content classes:
67+
68+
```csharp
69+
// Your content item must implement INamed
70+
public record Material(string Name, string Color, int Durability) : INamed;
71+
72+
// Your content collection must implement IContent<T>
73+
[Singleton]
74+
public partial class Materials : IContent<Material>
75+
{
76+
public Material[] All { get; } =
77+
[
78+
new("Steel", "Gray", 100),
79+
new("Wood", "Brown", 50),
80+
new("Gold", "Yellow", 25)
81+
];
82+
}
83+
```
84+
85+
The source generator automatically creates:
86+
87+
```csharp
88+
// Generated enum
89+
public enum MaterialsType
90+
{
91+
Steel,
92+
Wood,
93+
Gold
94+
}
95+
96+
// Generated helper methods
97+
public partial class Materials
98+
{
99+
public Material Get(MaterialsType type) => All[(int)type];
100+
public Material this[MaterialsType type] => All[(int)type];
101+
public Material GetById(int id) => All[id];
102+
public Material Steel => All[0];
103+
public Material Wood => All[1];
104+
public Material Gold => All[2];
105+
}
106+
```
107+
108+
Use the generated code:
109+
110+
```csharp
111+
var materials = host.Get<Materials>();
112+
113+
// Type-safe access using enums
114+
var steel = materials[MaterialsType.Steel];
115+
var wood = materials.Get(MaterialsType.Wood);
116+
117+
// Direct property access
118+
var gold = materials.Gold;
119+
120+
// Index-based access
121+
var firstMaterial = materials.GetById(0);
122+
```
123+
124+
## Advanced Features
125+
126+
### Performance Optimizations
127+
128+
The library includes `NamedComparer<T>` for efficient dictionary operations with `INamed` keys:
129+
130+
```csharp
131+
// Use ToNamedDictionary extension method
132+
var materialDict = materials.All.ToNamedDictionary(m => m.Durability);
133+
134+
// Or explicitly specify the comparer
135+
var dict = new Dictionary<Material, int>(new NamedComparer<Material>());
136+
```
137+
138+
### SubContent Collections
139+
140+
For hierarchical content organization:
141+
142+
```csharp
143+
public class WeaponStats : ISubContent<Material, int>
144+
{
145+
public Dictionary<Material, int> ByKey { get; }
146+
public int this[Material material] => ByKey[material];
147+
}
148+
```
149+
150+
### Roslyn Analyzers
151+
152+
The package includes analyzers that help you:
153+
- **NC001**: Ensures `Dictionary<TKey, TValue>` uses `NamedComparer<T>` for `INamed` keys
154+
- **TND001**: Suggests using `ToNamedDictionary()` instead of `ToDictionary()` for `INamed` keys
155+
156+
## Requirements
157+
158+
- .NET 8.0 or .NET 9.0
159+
- C# with nullable reference types enabled (recommended)
160+
161+
## How It Works
162+
163+
1. **Service Discovery**: The host scans all loaded assemblies for classes marked with lifetime attributes
164+
2. **Dependency Resolution**: Constructor parameters are automatically resolved from registered services
165+
3. **Source Generation**: The generator scans for classes implementing `IContent<T>` and generates enums and helper methods
166+
4. **Code Analysis**: Roslyn analyzers ensure best practices for dictionary usage with named keys
167+
168+
## Best Practices
169+
170+
- Use `[Singleton]` for stateless services and shared resources
171+
- Use `[Scoped]` for services that should be unique per operation/request
172+
- Use `[Transient]` for lightweight, stateless services that need fresh instances
173+
- Always implement `INamed` for content objects to enable source generation
174+
- Use the generated enums for type-safe content access
175+
- Leverage `ToNamedDictionary()` for performance when working with `INamed` collections
176+
177+
## License
178+
179+
MIT License - see the license file for details.

0 commit comments

Comments
 (0)