So you have static variable in web project and then add reference to web project to obtain that config? Do I get that right?
I never felt like config DI was a problem once you did all the stuff that you do at the beginning of the project
So you have static variable in web project and then add reference to web project to obtain that config? Do I get that right?
I never felt like config DI was a problem once you did all the stuff that you do at the beginning of the project
using Microsoft.Extensions.Configuration; //extra line
using Microsoft.Extensions.Options; //extra line
public class AdminController : Controller
{
IOptions<Settings> settings; //extra line
public AdminController(IOptions<Settings> settings) //extra code
{
this.settings = settings; //extra line
}
public void RandomMethod()
{
var a = settings.Value.FinallyMySetting; // 5 extra lines to access your config, genius...
}
}
A complete and utter waste of my time to put all those lines in, it's just pointless boilerplate trash, which C# has been getting rid of excellently, all to be undone by whoever wrote Microsoft.Extensions.Configuration. And you have to do it any where you want to get a config value.On top of that, if you want to use it in a console app, you have to add like 5 packages. Yes, FIVE.
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" />
Then add this delightful mess just to initialize it: var environmentName = Environment.GetEnvironmentVariable("ENVIRONMENT");
var builder = new ConfigurationBuilder()
.AddJsonFile($"appsettings.json", true, true)
.AddJsonFile($"appsettings.{environmentName}.json", true, true)
.AddEnvironmentVariables();
var configuration = builder.Build();
When you compare that to what any other framework does, it just beggars belief that they though this was a good way of handling config.When I was setting this all up, I obviously hit up SO, and it's clear from many of the (incorrect) answers on SO that people just don't get it. It's too complicated for something that should be super simple.
I get that it's handy to be able to configure all that yourself, but all of that should be default and a single line/package.
ASP.NET Core does push you strongly towards dependency injection, but it does not force you at all to use it.
Their own documentation for making queries against SQL Server doesn't provide examples of how to do it that aren't using DI. "Just inject it" it just says. Thanks .net, super helpful. Maybe the docs are there, but I couldn't find them at all when I went looking.
using(var conn = new SqlConnection("<conn-string>"))
using(var cmd = new SqlCommand(@"Query here", conn))
{
conn.Open();
cmd.executeNonQuery();
}It is something that annoys me about .NET in general there is just decades of over-engineering cruft and once these practices emerge its difficult to get people to stop doing them. The problem only gets worse as time passes.
It's such convoluted nonsense.
I like C# but sometimes it feels like MS main aim is to make developers miserable.
I don't regard the "ConfigurationBuilder" and following lines as "boilerplate" exactly, since by not using the default HostBuilder and instead including that code, you are making choices.
Specifically, you are choosing to pull in settings from "appsettings.json", "appsettings.{env}.json" and then environment vars, in that order, and specifying that both files are optional and should reload on change.
You can make other choices, with other code.The code is there to "configure the config", i.e. to make those choices.
> it's just pointless boilerplate trash, which C# has been getting rid of excellently
Could you elaborate on how you feel C# avoided this?
From my point of view the only alternative (to DI with constructor injection) is static members somewhere, which does not scale. Maybe property injection, but ugh.
For example:
test.appsettings.json
{"db-url":"test.url.here"}
prod.appsettings.json
{"db-url":"prod.url.here"}
Now in the code:
Settings.fetch("db-url");
// Will return the test one if environment variable says we are running under test environment, else will return the prod one.
A lot of the complexity in the configuration system exists to enable a lot of configuration options. I have some ASP.NET applications that get some configuration from Environment Variables on the host machine, some from environment-specific config files, some from a configuration service (specifically Azure Key Vault), all without any of my DI-injected downstream components specifically needing to know which source provided specifically which configuration key. For the DI injected things it is just `config["db-url"]` or maybe type-safe class if I DI-inject an IOptions<T> (or add my type-safe classes directly to the DI without the IOptions<T> wrapper, which is another configurable option).
It's absolutely a very complex system, but with great complexity comes great flexibility (to badly paraphrase the Spider-Man mantra).
I just type IOptions<T> config in ctor, use ctrl+. and private readonly property and it's initialization is generated
I just tried it.
https://i.imgur.com/cWs1M77.png
and I have some naming rule
https://i.imgur.com/iPwNj5b.png
So I basically have to type IOptions<T> Name and use ctrl+. twice in order to generate private readonly property and initialize it and add using to IOptions
also as far as I heard, is that microsoft is working on a micro web framework, that does not use di. (something like https://github.com/featherhttp/framework, just more official i guess)
Can you show me what that looks like?