@@ -13,15 +13,17 @@ public class VaultConfigurationProvider
1313 : ConfigurationProvider , IDisposable
1414{
1515 private readonly VaultConfigurationSource _source ;
16- private readonly IVaultService ? _vaultService ;
16+ private readonly IVaultService _vaultService ;
1717 private readonly ILogger ? _logger ;
1818 private Timer ? _reloadTimer ;
1919 private bool _disposed ;
2020
2121 /// <summary>
2222 /// Initializes a new instance of the <see cref="VaultConfigurationProvider"/> class.
23- /// Main constructor used when VaultService is already available.
2423 /// </summary>
24+ /// <param name="source">The configuration source.</param>
25+ /// <param name="vaultService">The Vault service instance.</param>
26+ /// <param name="logger">Optional logger for the provider.</param>
2527 public VaultConfigurationProvider (
2628 VaultConfigurationSource source ,
2729 IVaultService vaultService ,
@@ -38,22 +40,6 @@ public VaultConfigurationProvider(
3840 }
3941 }
4042
41- /// <summary>
42- /// Initializes a new instance of the <see cref="VaultConfigurationProvider"/> class.
43- /// Constructor for compatibility with IConfigurationSource.Build
44- /// VaultService will be injected later via SetVaultService.
45- /// </summary>
46- internal VaultConfigurationProvider ( VaultConfigurationSource source )
47- {
48- _source = source ?? throw new ArgumentNullException ( nameof ( source ) ) ;
49-
50- if ( string . IsNullOrWhiteSpace ( _source . Environment ) )
51- {
52- throw new InvalidOperationException (
53- "Vault environment must be specified (e.g., DEV, PROD)" ) ;
54- }
55- }
56-
5743 /// <summary>
5844 /// Load secrets from Vault.
5945 /// </summary>
@@ -79,28 +65,6 @@ public void Dispose()
7965 GC . SuppressFinalize ( this ) ;
8066 }
8167
82- /// <summary>
83- /// Inject VaultService after creation (used by extension method).
84- /// </summary>
85- internal void SetVaultService ( IVaultService vaultService , ILogger < VaultConfigurationProvider > ? logger = null )
86- {
87- if ( _vaultService != null )
88- {
89- throw new InvalidOperationException ( "VaultService already set" ) ;
90- }
91-
92- // Use reflection to assign the readonly field
93- var field = typeof ( VaultConfigurationProvider ) . GetField (
94- "_vaultService" ,
95- System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
96- field ? . SetValue ( this , vaultService ) ;
97-
98- var loggerField = typeof ( VaultConfigurationProvider ) . GetField (
99- "_logger" ,
100- System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
101- loggerField ? . SetValue ( this , logger ) ;
102- }
103-
10468 /// <summary>
10569 /// Convert an object value to string.
10670 /// </summary>
@@ -120,35 +84,60 @@ internal void SetVaultService(IVaultService vaultService, ILogger<VaultConfigura
12084 }
12185
12286 /// <summary>
123- /// Check if a value is JSON.
87+ /// Check if a value is JSON (object or array).
88+ /// Handles both string values and JsonElement values.
12489 /// </summary>
125- private static bool IsJsonValue ( object ? value )
90+ private static bool IsJsonValue ( object ? value , out string ? jsonString )
12691 {
127- if ( value is not string str )
92+ jsonString = null ;
93+
94+ if ( value == null )
12895 {
12996 return false ;
13097 }
13198
132- str = str . Trim ( ) ;
133- return ( str . StartsWith ( "{" ) && str . EndsWith ( "}" ) ) || ( str . StartsWith ( "[" ) && str . EndsWith ( "]" ) ) ;
134- }
135-
136- private async Task LoadAsync ( )
137- {
138- if ( _vaultService == null )
99+ // Handle JsonElement from VaultSharp
100+ if ( value is JsonElement jsonElement )
139101 {
140- var errorMessage = "VaultService is not initialized. " +
141- "Make sure to call AddVault() before AddVaultConfiguration()" ;
102+ if ( jsonElement . ValueKind == JsonValueKind . Object ||
103+ jsonElement . ValueKind == JsonValueKind . Array )
104+ {
105+ jsonString = jsonElement . GetRawText ( ) ;
106+ return true ;
107+ }
142108
143- if ( _source . Optional )
109+ if ( jsonElement . ValueKind == JsonValueKind . String )
144110 {
145- _logger ? . LogWarning ( errorMessage ) ;
146- return ;
111+ var str = jsonElement . GetString ( ) ? . Trim ( ) ;
112+ if ( ! string . IsNullOrEmpty ( str ) &&
113+ ( ( str . StartsWith ( "{" ) && str . EndsWith ( "}" ) ) ||
114+ ( str . StartsWith ( "[" ) && str . EndsWith ( "]" ) ) ) )
115+ {
116+ jsonString = str ;
117+ return true ;
118+ }
147119 }
148120
149- throw new InvalidOperationException ( errorMessage ) ;
121+ return false ;
122+ }
123+
124+ // Handle string values
125+ if ( value is string strValue )
126+ {
127+ var trimmed = strValue . Trim ( ) ;
128+ if ( ( trimmed . StartsWith ( "{" ) && trimmed . EndsWith ( "}" ) ) ||
129+ ( trimmed . StartsWith ( "[" ) && trimmed . EndsWith ( "]" ) ) )
130+ {
131+ jsonString = trimmed ;
132+ return true ;
133+ }
150134 }
151135
136+ return false ;
137+ }
138+
139+ private async Task LoadAsync ( )
140+ {
152141 try
153142 {
154143 _logger ? . LogInformation (
@@ -162,9 +151,9 @@ private async Task LoadAsync()
162151 foreach ( var kvp in secrets )
163152 {
164153 // If the value is JSON, flatten it
165- if ( IsJsonValue ( kvp . Value ) )
154+ if ( IsJsonValue ( kvp . Value , out var jsonString ) )
166155 {
167- FlattenJsonValue ( kvp . Key , kvp . Value , data ) ;
156+ FlattenJsonValue ( kvp . Key , jsonString , data ) ;
168157 }
169158 else
170159 {
@@ -229,11 +218,11 @@ private void LoadAndNotifyChange()
229218 }
230219
231220 /// <summary>
232- /// Flatten a JSON value into dotted keys with dot notation .
221+ /// Flatten a JSON value into configuration keys.
233222 /// </summary>
234- private void FlattenJsonValue ( string parentKey , object ? value , Dictionary < string , string ? > data )
223+ private void FlattenJsonValue ( string parentKey , string ? jsonString , Dictionary < string , string ? > data )
235224 {
236- if ( value is not string jsonString )
225+ if ( string . IsNullOrEmpty ( jsonString ) )
237226 {
238227 return ;
239228 }
0 commit comments