Thursday, April 2, 2020

Use a better ConfigurationBuilder instantiation for getting at appsettings.json variables in .NET Core 3.

Outside of a Controller or PageModel (WebMatrix), I had this trick, but here is a better way to go in modern times. It uses the Microsoft.Extensions.Configuration using declaration.

IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json",
      optional: true, reloadOnChange: true).Build();
string thing = config["Repositories"];

 
 

Oh, it turns out that .AddJsonFile is an extension method from Microsoft.Extensions.Configuration.Json so you need that too. Castle.Core.Configuration may have an IConfiguration also. The name is kinda weak.

Wednesday, April 1, 2020

ConfigureServices returning an System.IServiceProvider isn't supported.

Alright, if you are getting this error, you tried to loop in Autofac as described here and it did not work because you are using version 3 of the .NET Framework (or better). The fix is to undo what you did in ConfigureServices and instead, in Program.cs, add the third line you see below to the mix:

public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
         .UseServiceProviderFactory(new AutofacServiceProviderFactory())
         .ConfigureWebHostDefaults(webBuilder =>
         {
            webBuilder.UseStartup();
         });

 
 

Alright, now back at Startup.cs you need a new method called ConfigureContainer like so:

public void ConfigureContainer(ContainerBuilder builder)
{
   builder.RegisterType<Tom>().As<ITom>();
}

Use Autofac for IoC in .NET Core.

At: Tools > NuGet Package Manager > Manage NuGet Packages for Solution... ...search for "Autofac.Extensions.DependencyInjection" at the "Browse" tab. You will need the Autofac and Autofac.Extensions.DependencyInjection using declarations. Per this, the ConfigureServices method in Startup must change like so:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
   services.AddControllers();
   var builder = new ContainerBuilder();
   builder.RegisterModule(new Foo());
   builder.RegisterModule(new Bar("bar"));
   builder.RegisterModule<Baz>();
   builder.RegisterType<Qux>().As<IQux>().WithParameter(new
         TypedParameter(typeof(IServiceFactory), new ServiceFactory(new[] { new
         FilenetProvider() })));
   builder.RegisterType<Yin>().As<IYin>();
   builder.RegisterType<Yang>().As<IYang>().SingleInstance();
   builder.Populate(services);
   var container = builder.Build();
   return new AutofacServiceProvider(container);
}

.AllowCredentials()

I think that using .AllowCredentials() like .AllowAnyMethod() at Startup in a .NET Core application is equal to setting .SupportsCredentials to true at a CorsPolicy in the .NET Framework stuff.

Use .WithHeaders instead of .AllowAnyHeader in CORS in .NET Core.

.WithHeaders("GET", "POST", "PUT", "DELETE", "OPTIONS")

Allow all subdomains for a domain name in CORS in a .NET Core orchestration.

Follow this example and replace www with an * to make the magic happen.

Open up CORS for very specific domains in .NET Core 3.1.

This had this example:

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors(options =>
   {
      options.AddPolicy(MyAllowSpecificOrigins,
      builder =>
      {
         builder.WithOrigins("http://example.com",
               "http://www.contoso.com")
               .AllowAnyHeader()
               .AllowAnyMethod();
      });
   });
   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

 
 

MyAllowSpecificOrigins above is just a string and...

app.UseCors(MyAllowSpecificOrigins);

 
 

...needs to go inside of:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{