@@ -36,27 +36,24 @@ namespace TransactionProcessor.Bootstrapper
3636 [ ExcludeFromCodeCoverage ]
3737 public class RepositoryRegistry : ServiceRegistry
3838 {
39- #region Constructors
39+ private static bool CachedAggregatesAdded ;
40+ private static readonly object CachedAggregatesLock = new ( ) ;
4041
41- private static Boolean CachedAggregatesAdded ;
42- /// <summary>
43- /// Initializes a new instance of the <see cref="RepositoryRegistry"/> class.
44- /// </summary>
4542 public RepositoryRegistry ( )
4643 {
47- String eventStoreConnectionString = Startup . Configuration . GetValue < String > ( "EventStoreSettings:ConnectionString" ) ;
44+ string eventStoreConnectionString = Startup . Configuration . GetValue < string > ( "EventStoreSettings:ConnectionString" ) ;
4845
4946 this . AddEventStoreProjectionManagementClient ( eventStoreConnectionString ) ;
5047 this . AddEventStorePersistentSubscriptionsClient ( eventStoreConnectionString ) ;
51-
5248 this . AddEventStoreClient ( eventStoreConnectionString ) ;
5349
54- this . AddSingleton < Func < String , Int32 , ISubscriptionRepository > > ( cont => ( esConnString , cacheDuration ) => {
55- return SubscriptionRepository . Create ( esConnString , cacheDuration ) ;
56- } ) ;
50+ this . AddSingleton < Func < string , int , ISubscriptionRepository > > ( cont => ( esConnString , cacheDuration ) =>
51+ SubscriptionRepository . Create ( esConnString , cacheDuration ) ) ;
5752
5853 this . AddSingleton ( typeof ( IDbContextResolver < > ) , typeof ( DbContextResolver < > ) ) ;
59- if ( Startup . WebHostEnvironment . IsEnvironment ( "IntegrationTest" ) || Startup . Configuration . GetValue < Boolean > ( "ServiceOptions:UseInMemoryDatabase" ) == true )
54+
55+ if ( Startup . WebHostEnvironment . IsEnvironment ( "IntegrationTest" ) ||
56+ Startup . Configuration . GetValue < bool > ( "ServiceOptions:UseInMemoryDatabase" ) )
6057 {
6158 this . AddDbContext < EstateManagementContext > ( builder => builder . UseInMemoryDatabase ( "TransactionProcessorReadModel" ) ) ;
6259 }
@@ -67,28 +64,37 @@ public RepositoryRegistry()
6764 }
6865
6966 this . AddTransient < IEventStoreContext , EventStoreContext > ( ) ;
70- this . AddSingleton < Func < IAggregateService > > ( c => ( ) => {
71-
72- IAggregateService aggregateService = Startup . ServiceProvider . GetService < IAggregateService > ( ) ;
73- if ( RepositoryRegistry . CachedAggregatesAdded == false )
67+
68+ // ✅ Defer to the container — safe and compliant
69+ this . AddSingleton < Func < IAggregateService > > ( c => ( ) =>
70+ {
71+ var aggregateService = c . GetService < IAggregateService > ( ) ;
72+
73+ // Thread-safe single initialization
74+ if ( ! CachedAggregatesAdded )
7475 {
75- aggregateService . AddCachedAggregate ( typeof ( EstateAggregate ) , null ) ;
76- aggregateService . AddCachedAggregate ( typeof ( ContractAggregate ) , null ) ;
77- aggregateService . AddCachedAggregate ( typeof ( OperatorAggregate ) , null ) ;
78- aggregateService . AddCachedAggregate ( typeof ( MerchantAggregate ) , null ) ;
79- RepositoryRegistry . CachedAggregatesAdded = true ;
76+ lock ( CachedAggregatesLock )
77+ {
78+ if ( ! CachedAggregatesAdded )
79+ {
80+ aggregateService . AddCachedAggregate ( typeof ( EstateAggregate ) , null ) ;
81+ aggregateService . AddCachedAggregate ( typeof ( ContractAggregate ) , null ) ;
82+ aggregateService . AddCachedAggregate ( typeof ( OperatorAggregate ) , null ) ;
83+ aggregateService . AddCachedAggregate ( typeof ( MerchantAggregate ) , null ) ;
84+
85+ CachedAggregatesAdded = true ;
86+ }
87+ }
8088 }
81-
89+
8290 return aggregateService ;
8391 } ) ;
92+
8493 this . AddSingleton < IAggregateService , AggregateService > ( ) ;
8594 this . AddSingleton < IAggregateRepositoryResolver , AggregateRepositoryResolver > ( ) ;
86- this . AddSingleton < IAggregateRepository < TransactionAggregate , DomainEvent > ,
87- AggregateRepository < TransactionAggregate , DomainEvent > > ( ) ;
88- this . AddSingleton < IAggregateRepository < ReconciliationAggregate , DomainEvent > ,
89- AggregateRepository < ReconciliationAggregate , DomainEvent > > ( ) ;
90- this . AddSingleton < IAggregateRepository < SettlementAggregate , DomainEvent > ,
91- AggregateRepository < SettlementAggregate , DomainEvent > > ( ) ;
95+ this . AddSingleton < IAggregateRepository < TransactionAggregate , DomainEvent > , AggregateRepository < TransactionAggregate , DomainEvent > > ( ) ;
96+ this . AddSingleton < IAggregateRepository < ReconciliationAggregate , DomainEvent > , AggregateRepository < ReconciliationAggregate , DomainEvent > > ( ) ;
97+ this . AddSingleton < IAggregateRepository < SettlementAggregate , DomainEvent > , AggregateRepository < SettlementAggregate , DomainEvent > > ( ) ;
9298 this . AddSingleton < IAggregateRepository < VoucherAggregate , DomainEvent > , AggregateRepository < VoucherAggregate , DomainEvent > > ( ) ;
9399 this . AddSingleton < IAggregateRepository < FloatAggregate , DomainEvent > , AggregateRepository < FloatAggregate , DomainEvent > > ( ) ;
94100 this . AddSingleton < IAggregateRepository < FloatActivityAggregate , DomainEvent > , AggregateRepository < FloatActivityAggregate , DomainEvent > > ( ) ;
@@ -99,17 +105,15 @@ public RepositoryRegistry()
99105 this . AddSingleton < IAggregateRepository < MerchantDepositListAggregate , DomainEvent > , AggregateRepository < MerchantDepositListAggregate , DomainEvent > > ( ) ;
100106 this . AddSingleton < IAggregateRepository < MerchantStatementAggregate , DomainEvent > , AggregateRepository < MerchantStatementAggregate , DomainEvent > > ( ) ;
101107 this . AddSingleton < IAggregateRepository < MerchantStatementForDateAggregate , DomainEvent > , AggregateRepository < MerchantStatementForDateAggregate , DomainEvent > > ( ) ;
102-
103108 this . AddSingleton < IProjectionStateRepository < MerchantBalanceState > , MerchantBalanceStateRepository > ( ) ;
104109 this . AddSingleton < IProjectionStateRepository < VoucherState > , VoucherStateRepository > ( ) ;
105110 this . AddSingleton < ITransactionProcessorReadRepository , TransactionProcessorReadRepository > ( ) ;
106111 this . AddSingleton < ITransactionProcessorReadModelRepository , TransactionProcessorReadModelRepository > ( ) ;
107112 this . AddSingleton < IProjection < MerchantBalanceState > , MerchantBalanceProjection > ( ) ;
108113 }
109-
110- #endregion
111114 }
112115
116+
113117 [ ExcludeFromCodeCoverage ]
114118 public class ConfigurationReaderConnectionStringRepository : IConnectionStringConfigurationRepository
115119 {
0 commit comments