AddSystemsManager breaks other Json providers
See original GitHub issueDescription
When using AddSystemsManager after other providers based on JSON, the other provider is executed twice, throwing an exception.
Reproduction Steps
- Create a console project with the following package references
<PackageReference Include="Amazon.Extensions.Configuration.SystemsManager" Version="2.1.0" />
<PackageReference Include="Kralizek.Extensions.Configuration.Objects" Version="1.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
- Add the following code in
Program.cs
(relevant namespaces missing)
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddObject(new { Foo = "Bar" }, "Test");
configurationBuilder.AddSystemsManager($"/some/key/to/import");
var configuration = configurationBuilder.Build();
The following exception was thrown: System.FormatException: 'A duplicate key 'Test:Foo' was found.'
- The same doesn’t happen when:
configurationBuilder.AddSystemsManager($"/some/key/to/import");
is commented outconfigurationBuilder.AddSystemsManager($"/some/key/to/import");
is placed beforeconfigurationBuilder.AddObject(new { Foo = "Bar" });
- two calls to AddObject are added with different objects:
configurationBuilder.AddObject(new { Foo = "Bar" }, "Test");
configurationBuilder.AddObject(new { Hello = "World" }, "Test");
Logs
System.FormatException
HResult=0x80131537
Message=A duplicate key 'Test:Foo' was found.
Source=Kralizek.Extensions.Configuration.Objects
StackTrace:
at Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.VisitPrimitive(JValue data)
at Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.VisitToken(JToken token)
at Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.VisitJObject(JObject jObject)
at Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.Serialize(Object source, String rootSectionName)
at Kralizek.Extensions.Configuration.Internal.ObjectConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at ConfigurationSample.Program.<Main>d__0.MoveNext() in C:\Users\RenatoGolia\Development\InsightArchitectures\samples\ConfigurationSample\Program.cs:line 26
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at ConfigurationSample.Program.<Main>(String[] args)
This exception was originally thrown at this call stack:
Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.VisitPrimitive(Newtonsoft.Json.Linq.JValue)
Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.VisitToken(Newtonsoft.Json.Linq.JToken)
Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.VisitJObject(Newtonsoft.Json.Linq.JObject)
Kralizek.Extensions.Configuration.Internal.JsonConfigurationSerializer.Serialize(object, string)
Kralizek.Extensions.Configuration.Internal.ObjectConfigurationProvider.Load()
Microsoft.Extensions.Configuration.ConfigurationRoot.ConfigurationRoot(System.Collections.Generic.IList<Microsoft.Extensions.Configuration.IConfigurationProvider>)
Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
ConfigurationSample.Program.Main(string[]) in Program.cs
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
...
[Call Stack Truncated]
I realize that the error occurs in the other library, but I created this issue because the error occurs when AddSystemsManager is added after the other provider.
Environment
- Build Version: 2.1.0
- OS Info: Windows 10
- Build Environment: dotnet run
- Targeted .NET Platform: net 5.0
Resolution
- 👋 I can/would-like-to implement a fix for this problem myself
I suspect the provider behind AddSystemsManager
somehow executes other providers again but I couldn’t find the source of the bug.
This is a 🐛 bug-report
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (2 by maintainers)
Top Results From Across the Web
C# AWS Parameter Store - Configuration not loading ...
It is always talking to appsettings.json. I tried debugging locally, still same behavior. Not able to find the SystemManagerConfiguration under ...
Read more >NET Core configuration provider for AWS Systems Manager
This NuGet package simplifies how your application loads the application configuration settings in the AWS Systems Manager Parameter Store into ...
Read more >Discovering AWS for .NET Developers
Learn a bit about how Amazon Web Services (AWS) supports .NET platforms including hosting ASP.NET Core apps.
Read more >Configuring ASP.NET Core In AWS - Cold-Brewed DevOps
json file and the environment variables, CreateDefaultBuilder() sets up several configuration providers. According to the documentation, it sets ...
Read more >C# (CSharp) AWSOptions Examples
C# (CSharp) AWSOptions - 37 examples found. These are the top rated real world C# (CSharp) examples of AWSOptions extracted from open source...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Thanks @KenHundley for your quick reply. I’ll look into the change you suggested 😃
Hey @Kralizek, that’s correct that it does load some of the sources, depending on the situation. If you don’t directly supply the AWSOptions object to the AddSystemsManager call then it’ll build the previous sources in a attempt discover the necessary AWS configuration data, like profile, region, etc.
For example:
will build the CommandLine and EnvironmentVariables sources and look for the necessary AWS configuration data. This happens here: SystemsManagerExtensions.cs Since the sources are executed in order they are added to the builder it always finds the ones above the
AddSystemsManager
call.One way to solve this is to explicitly create the AWSOptions object and pass it to the
AddSystemsManager
call. Since the extenion has all that it needs it does not execute the previous sources.Also, I have a suggestion for your https://github.com/Kralizek/ObjectConfigurationExtensions project. The issue is occuring because you are creating the json serializer object when the source is created and it has a class level variable in the serializer class that holds all previous data. If you were to move the seralizer creation to the load then you would also prevent this issue since the _data object wouldn’t already have the previous execution. Since the load is only executed when the configuration is built it shouldn’t have any performance impact. btw, I did a quick test with this serializer change and the issue disappeared.