V10 Migration Guide
Overview
Brighter V10 introduces significant improvements and new features while maintaining a clear migration path from V9. This guide provides step-by-step instructions for upgrading your application to V10, addressing breaking changes, and adopting new features.
Key Changes in V10:
Cloud Events support
OpenTelemetry Semantic Conventions
Default Message Mappers
Dynamic Message Deserialization
Nullable Reference Types (breaking)
Simplified Configuration (breaking)
Reactor and Proactor terminology (breaking)
Polly Resilience Pipeline v8 (breaking)
Request Context enhancements
InMemory options for testing
Transport improvements (PostgreSQL, RabbitMQ, Kafka, AWS)
Request ID is now an
Idtype
Migration Effort: Most applications can be migrated in 1-4 hours, depending on complexity.
Before You Start
Prerequisites
Backup your code: Commit all changes to version control
Review the release notes: Read Release Notes for V10
Update test suite: Ensure your tests are passing on V9
Check dependencies: Review third-party package compatibility
Recommended Migration Approach
Upgrade in a feature branch: Don't upgrade directly in main/master
Address breaking changes first: Fix compilation errors before adopting new features
Test thoroughly: Run your full test suite after each step
Deploy to staging: Validate in a non-production environment
Monitor production: Watch for issues after deployment
Step 1: Update Package References
Update NuGet Packages
Update all Brighter packages to V10:
Check for Package Conflicts
Step 2: Address Breaking Changes
1. Nullable Reference Types
Breaking Change: Nullable reference types are now enabled across all Brighter projects.
Migration Steps:
Enable nullable reference types in your project (if not already enabled):
Address compiler warnings in Commands, Events, and Handlers:
Before (V9):
After (V10):
Update Message Mappers to handle nullable warnings:
See also: Nullable Reference Types Documentation
2. Simplified Configuration
Breaking Change: Builder methods renamed for clarity.
Before (V9):
After (V10):
Migration Steps:
Replace
UseExternalBuswithAddProducersReplace
AddServiceActivatorwithAddConsumersUpdate property names:
ProducerRegistryinstead of passing directly
3. Reactor and Proactor Terminology
Breaking Change: The runAsync flag on Subscription has been renamed to MessagePumpType.
Before (V9):
After (V10):
Migration Table:
runAsync: false
messagePumpType: MessagePumpType.Reactor
Synchronous, blocking I/O
runAsync: true
messagePumpType: MessagePumpType.Proactor
Asynchronous, non-blocking I/O
See also: Reactor and Proactor Documentation
4. Polly Resilience Pipeline
Breaking Change: TimeoutPolicyAttribute is obsolete. Use UseResiliencePipeline attribute.
Before (V9):
After (V10):
Define a Resilience Pipeline:
Use the new attribute:
Register the pipeline with Brighter:
See also: Policy Retry and Circuit Breaker Documentation
5. Request Context Interface Changes
Breaking Change: IRequestContext interface has new properties.
New Properties:
PartitionKey: Set message partition keys dynamicallyCustomHeaders: Add custom headers via request contextResilienceContext: Integration with Polly resilience pipelineOriginatingMessage: Access the original message (for consumers)
Migration: Most code should not be affected unless you implement IRequestContext directly.
If you implement IRequestContext (rare):
Using new properties:
6. Request Id and CorrelationId type change
In V9 the Request type used a Guid to represent the identity of a Command or Event. In V10, as part of a move away from primitives, we have changed this to be a type Id. An Id can be constructed from a string using its ToString() method. If you have used a Guid then you will need to turn the Guid into a string.
Within IRequest both Id and CorrelationId both use the type Id in V10.
If you were using a Guid to create a random identity, you can just use Id.Random() instead which has the same behavior.
Before:
After:
Step 3: Adopt New Features (Optional)
1. Cloud Events Support
V10 adds full Cloud Events specification support.
Benefits:
Standardized event metadata
Better interoperability with other systems
Rich event context information
Adoption Steps:
Update Publication to include Cloud Events properties:
Use Cloud Events headers in your mapper (optional):
See also: Cloud Events Documentation
2. Default Message Mappers
V10 allows you to omit message mappers for simple JSON serialization.
Benefits:
Less boilerplate code
Faster development
Still supports custom mappers for complex scenarios
Before (V9) - Required Mapper:
After (V10) - No Mapper Needed:
When to use custom mappers:
Complex transformations
Non-JSON formats (XML, Protobuf, etc.)
Transform pipelines (encryption, compression, claim check)
Custom header mapping
See also: Message Mappers Documentation
3. Dynamic Message Deserialization
V10 supports multiple message types on the same channel.
Benefits:
Content-based routing
Flexible message processing
Better use of infrastructure
Example:
See also: Dynamic Deserialization Documentation
4. OpenTelemetry Semantic Conventions
V10 adopts OpenTelemetry Semantic Conventions for messaging.
Impact: Trace spans will have different names and attributes than V9.
Benefits:
Standard messaging conventions
Better integration with APM tools
Consistent telemetry across systems
Migration:
Update dashboards and alerts to use new span names
Review trace queries for compatibility
Test observability in staging environment
V9 Span Names:
Paramore.Brighter.CommandProcessor.SendParamore.Brighter.MessagePump.Receive
V10 Span Names (OTel Semantic Conventions):
messaging.sendmessaging.receivemessaging.process
See also: Telemetry Documentation
5. InMemory Options for Testing
V10 provides comprehensive InMemory implementations for testing.
Benefits:
Fast test execution
No external dependencies
Easy CI/CD integration
Example:
See also: InMemory Options Documentation
Step 4: Test Your Migration
Unit Tests
Run existing unit tests:
Address test failures:
Update mocks for
IRequestContextnew propertiesUpdate assertions for OpenTelemetry span names
Fix nullable reference warnings
Integration Tests
Test with InMemory components (fast):
Test with real transports (slower, more complete):
Performance Testing
Compare V9 and V10 performance:
Expected: V10 should have similar or better performance due to optimizations.
Step 5: Deploy to Staging
Pre-Deployment Checklist
Deployment Steps
Deploy to staging environment
Run smoke tests
Monitor metrics:
Message processing latency
Error rates
Resource usage (CPU, memory)
Check logs for warnings or errors
Validate telemetry (traces, metrics)
Monitoring
Watch for:
Increased error rates
Performance degradation
OpenTelemetry trace issues
Null reference exceptions
Step 6: Deploy to Production
Production Deployment
Deploy during low-traffic period
Use blue-green or canary deployment if possible
Monitor closely for first 24 hours
Have rollback plan ready
Post-Deployment
Review logs for issues
Check application metrics
Validate message processing
Monitor OpenTelemetry traces
Common Migration Issues
Issue 1: Nullable Reference Warnings
Symptom: CS8618, CS8600, CS8602 warnings
Solution: See Nullable Reference Types Documentation
Issue 2: Method Not Found
Symptom: UseExternalBus method not found
Solution: Replace with AddProducers
Issue 3: Property Not Found on Subscription
Symptom: runAsync property does not exist
Solution: Use messagePumpType: MessagePumpType.Proactor or MessagePumpType.Reactor
Issue 4: TimeoutPolicy Not Working
Symptom: TimeoutPolicyAttribute marked as obsolete
Solution: Migrate to UseResiliencePipeline with Polly v8
Issue 5: Telemetry Spans Changed
Symptom: Dashboard queries not finding spans
Solution: Update queries to use OpenTelemetry Semantic Convention names
Rollback Plan
If you need to roll back to V9:
Revert package versions:
Revert code changes:
Redeploy V9 version
Investigate issues before attempting V10 migration again
Getting Help
Resources
Reporting Issues
If you encounter issues during migration:
Check existing issues: Search GitHub Issues
Create a new issue with:
V9 and V10 versions
Minimal reproduction example
Error messages and stack traces
Environment details (.NET version, OS, transport)
Summary
Migrating to Brighter V10 involves:
Update packages to V10
Address breaking changes:
Nullable reference types
Simplified configuration API
Reactor/Proactor terminology
Polly Resilience Pipeline
Adopt new features (optional):
Cloud Events
Default message mappers
Dynamic deserialization
OpenTelemetry conventions
InMemory testing options
Test thoroughly
Deploy to staging, then production
Monitor and address any issues
Most migrations can be completed in 1-4 hours. The breaking changes are straightforward, and V10 provides significant improvements in features, performance, and developer experience.
Good luck with your migration! 🚀
Last updated
Was this helpful?
