DEV Community

Julia Shevchenko
Julia Shevchenko

Posted on • Edited on

2 1 1 1

How to Parse Environment Variables into DTO in .NET: AWS S3 Bucket Example

Working with objects is always better than with "magical" strings. Having multiple configuration strings for some services can be uncomfortable to work with. Also, it increases the number of parameters to pass to a service. If you add one more parameter to the configuration section, you will need to manually retrieve it from the configuration and pass it to the service, where it will be used.

Treating configuration settings as a DTO class will make your code more readable.

Parse config into DTO class

As an example, I have a configuration for an AWS S3 bucket in appsettings.json

"AwsS3": {
  "AccessKey": "your-access-key",
  "SecretKey": "your-secret-key",
  "BucketName": "your-bucket-name",
  "Region": "us-east-1"
},
Enter fullscreen mode Exit fullscreen mode

Let's create a DTO class for it:

public class AwsS3Settings
{
    public string AccessKey { get; set; } = string.Empty;
    public string SecretKey { get; set; } = string.Empty;
    public string BucketName { get; set; } = string.Empty;
    public string Region { get; set; } = string.Empty;
}
Enter fullscreen mode Exit fullscreen mode

Now, it's time to configure the dependency injection container to store our configuration. This code reads the configuration section, maps it to the AwsS3Settings class, wraps it with IOptions<T>, and adds it to the container as an IOptions<AwsS3Settings>.

builder.Services.Configure<AwsS3Settings(builder.Configuration.GetSection("AwsS3"));
Enter fullscreen mode Exit fullscreen mode

It means now it is possible to inject it in some service like this:

public class AwsS3Saver(IOptions<AwsS3Settings> settings
Enter fullscreen mode Exit fullscreen mode

If you want to inject your configuration DTO directly, without IOptions cover, you can register it as a Singleton in the container.

builder.Services.AddSingleton(sp => sp.GetRequiredService<IOptions<AwsS3Settings>>().Value);
Enter fullscreen mode Exit fullscreen mode

Then, you will be able to inject the DTO directly to any service:

public class AwsS3Saver(AwsS3Settings settings)
Enter fullscreen mode Exit fullscreen mode

Parse config into Record

Usually, such data is treated using a record, not a plain class. However, the record cannot be used to map configurations into it in the same way. If you try, you will get an exception: System.MissingMethodException: Cannot dynamically create an instance of type 'EnvToDtoDemo.Settings.AwsS3SettingsRecord'. Reason: No parameterless constructor defined.
The reason behind that is in IOptions<T>, which requires parameterless constructor and set; for a public properties.
Records use constructors with parameters and use them to initialize properties, so they can be set only during initialization, which makes them immutable.

However, you still can use records for parsing environment variables, but with a slightly different approach. Use Get extension method to map configuration to a strongly typed object, which is our AwsS3SettingsRecord. After that, add it to the container.

public record AwsS3SettingsRecord(string AccessKey, string SecretKey, string BucketName, string Region);

var awsS3SettingsRecord = builder.Configuration.GetSection("AwsS3").Get<AwsS3SettingsRecord>()
                    ?? throw new InvalidOperationException("AwsS3 settings are missing!");

builder.Services.AddSingleton(awsS3SettingsRecord);

Enter fullscreen mode Exit fullscreen mode

That's it! Now you can inject the record with configuration where needed.

🖖 Enjoy your coding!

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (2)

Collapse
 
igor_sh_dev profile image
Igor Igor

awesome

Collapse
 
juliashevchenko profile image
Julia Shevchenko

Thanks for reading!

AI Agent image

How to Build an AI Agent with Semantic Kernel (and More!)

Join Developer Advocate Luce Carter for a hands-on tutorial on building an AI-powered dinner recommendation agent. Discover how to integrate Microsoft Semantic Kernel, MongoDB Atlas, C#, and OpenAI for ingredient checks and smart restaurant suggestions.

Watch the video 📺

👋 Kindness is contagious

Value this insightful article and join the thriving DEV Community. Developers of every skill level are encouraged to contribute and expand our collective knowledge.

A simple “thank you” can uplift someone’s spirits. Leave your appreciation in the comments!

On DEV, exchanging expertise lightens our path and reinforces our bonds. Enjoyed the read? A quick note of thanks to the author means a lot.

Okay