Skip to content

Commit 118123b

Browse files
committed
Document DI and STJ modernization plan
1 parent 16a7730 commit 118123b

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
date: 2026-07-12
3+
topic: modern-di-stj
4+
---
5+
6+
# Modern DI and System.Text.Json
7+
8+
## What We're Building
9+
10+
Modernize the Exceptionless .NET client without requiring consumers to rewrite their existing setup. Replace the vendored internal Newtonsoft.Json fork with System.Text.Json while preserving the collector wire format, persisted queue compatibility, exclusions, depth limits, and arbitrary `DataDictionary` values. Replace TinyIoC with Microsoft.Extensions.DependencyInjection behind the existing `IDependencyResolver`, and add an `IServiceCollection` customization seam for new integrations.
11+
12+
## Why This Approach
13+
14+
A direct removal of `IDependencyResolver` would break configuration extensions, plugins, legacy platforms, isolated clients, and applications that do not use the Generic Host. Keeping TinyIoC indefinitely avoids that break but leaves the client with a private container implementation and prevents normal Microsoft DI customization. The staged adapter approach modernizes the implementation now, makes Microsoft DI the extensibility path, and leaves removal of the compatibility facade for a future major release.
15+
16+
The STJ migration already exists as four focused commits on `niemyjski/drop-json-net-use-stj`. Reusing and rebasing that work is lower-risk than independently recreating its converters and regression fixes.
17+
18+
## Key Decisions
19+
20+
- Preserve `IDependencyResolver` and all existing `ExceptionlessClient` constructors in this release.
21+
- Back `DefaultDependencyResolver` with `Microsoft.Extensions.DependencyInjection` singleton registrations.
22+
- Preserve unregistered concrete-type activation and replacement registration behavior.
23+
- Allow explicit `IServiceCollection` customization before the resolver is used.
24+
- Keep Exceptionless' internally owned provider isolated from an application's root provider; hosted apps continue resolving `ExceptionlessClient` from application DI.
25+
- Treat serialized JSON as a compatibility contract, not merely valid JSON.
26+
- Keep STJ converters reflection-based for `netstandard2.0` and `net462` compatibility; source generation can be a later optimization.
27+
28+
## Open Questions
29+
30+
- Removing `IDependencyResolver` and making every internal service directly application-DI-owned is deferred to a future major version.
31+
- A separate performance benchmark can decide whether STJ source generation is worth the additional model metadata surface.
32+
33+
## Next Steps
34+
35+
Implement the plan in `docs/plans/2026-07-12-modern-di-stj-plan.md` and verify focused serializer, resolver, storage, hosting, and full non-Windows test coverage.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Modern DI and System.Text.Json implementation plan
2+
3+
## Compatibility baseline
4+
5+
1. Run the current non-Windows solution tests before editing.
6+
2. Inventory exact JSON assertions, storage round-trips, resolver semantics, hosting registrations, and package target frameworks.
7+
8+
## System.Text.Json
9+
10+
1. Rebase the existing `niemyjski/drop-json-net-use-stj` commits onto current `main`.
11+
2. Resolve package-version and current-main conflicts without weakening serializer tests.
12+
3. Retain exact collector property names, enum strings, null/default output, `DataDictionary` raw-value markers, settings coercion, POST data behavior, exclusions, maximum depth, and stream ownership.
13+
4. Run focused serializer, storage, configuration exclusion, submission, and MessagePack tests.
14+
15+
## Dependency injection
16+
17+
1. Add Microsoft.Extensions.DependencyInjection to the core package for all supported targets.
18+
2. Replace TinyIoC in `DefaultDependencyResolver` with an `IServiceCollection`-backed provider.
19+
3. Preserve the existing registration lifetimes: interface/abstract mappings are singletons, concrete mappings and factories are transient, and explicit instances remain externally owned singletons.
20+
4. Preserve isolated resolvers, constructor injection, singleton resolution, unregistered concrete activation, null argument behavior, disposal, and registrations made after an initial resolution.
21+
5. Add a constructor/customization seam that accepts an `IServiceCollection` so new code can use normal Microsoft DI registrations without depending on the legacy methods.
22+
6. Add focused tests for service collection customization, replacement registration, late registration, and disposable singleton ownership.
23+
24+
## Validation and readiness
25+
26+
1. Build the non-Windows solution with warnings as errors.
27+
2. Run the complete non-Windows test suite.
28+
3. Pack the core and modern platform projects to catch dependency/package metadata issues.
29+
4. Inspect the final diff for accidental API breaks and remaining Newtonsoft/TinyIoC references.
30+
5. Document Windows-only validation that still needs CI when it cannot be run on macOS.
31+
32+
## Execution results
33+
34+
- Baseline: 300 core tests and 10 MessagePack tests passed; 18 existing tests were skipped.
35+
- Final non-Windows suite: 313 core tests and 10 MessagePack tests passed; 0 failed; the same 18 tests were skipped.
36+
- Focused DI coverage now includes singleton and transient compatibility, constructor injection, isolated containers, late replacement, `IServiceCollection` overrides, open generics, container disposal, external instance ownership, and host-provider disposal of the default client.
37+
- Serializer coverage retains exact wire-format assertions and adds regressions for exclusions, depth limits, `DataDictionary` structured/raw values, settings coercion, and MessagePack marker round-trips.
38+
- `net462` core and `net472` test assemblies build with 0 warnings and 0 errors when Windows targeting is forced on macOS. Runtime execution of the .NET Framework tests still belongs in Windows CI.
39+
- The non-Windows solution packs successfully. A Windows-shaped core package containing both `net462` and `netstandard2.0` assets also packs successfully with explicit `SolutionDir`.

0 commit comments

Comments
 (0)