sl8er
sl8er
CC#
Created by sl8er on 1/9/2025 in #help
Overriding appsettings.json section with environment variable
Given a configuration section called Tenants, I'd like to override it with a whole JSON structure via an environment variable. Given I want this
"Tenants": {
"ByCode": {
"11": {
"Name": "acme"
},
"42": {
"Name": "silver"
}
}
}
"Tenants": {
"ByCode": {
"11": {
"Name": "acme"
},
"42": {
"Name": "silver"
}
}
}
I'm doing
export Tenants='{"ByCode": {"11": {"Name": "acme"}, "42": {"Name": "silver"}}}'
export Tenants='{"ByCode": {"11": {"Name": "acme"}, "42": {"Name": "silver"}}}'
I'm trying to bind it against an object with the options pattern:
builder.Services.Configure<TenantsOptions>(
builder.Configuration.GetSection(TenantsOptions.SectionName));
builder.Services.Configure<TenantsOptions>(
builder.Configuration.GetSection(TenantsOptions.SectionName));
And the classes look like:
public class TenantsOptions
{
public const string SectionName = "Tenants";

public Dictionary<string, Tenant> ByCode { get; set; } = new();
}

public class Tenant
{
public string Name { get; set; }
}
public class TenantsOptions
{
public const string SectionName = "Tenants";

public Dictionary<string, Tenant> ByCode { get; set; } = new();
}

public class Tenant
{
public string Name { get; set; }
}
When I run the ASP.NET Core app, the ByCode dictionary is empty. But if I just paste the JSON section in appsettings.json, it's correctly populated. For the record, I can see the whole structure if I just log builder.Configuration.GetSection(TenantsOptions.SectionName).Value;, but for some reason, I guess it's only interpreted as a string, and not correctly deserialized and bound to TenantOptions? So how do you actually override a whole section with a JSON value through an environment variable?
25 replies
CC#
Created by sl8er on 5/27/2023 in #help
EF Core Many-to-One (Many Owned Entity to Non-owned Entity)
In the context of a multi-tenant application, I want to design an aggregate like so - a root Customer has a List<Address>, Address being an owned type. A Customer also references a Tenant. If I also want Address to reference a Tenant, it seems EF Core isn't happy when trying to configure a Tenant like so:
// This is fine.
builder
.HasMany<Customer>()
.WithOne(x => x.Tenant)
.HasForeignKey("tenant_id")
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);

// This throws - System.InvalidOperationException: The entity type 'Address' cannot be configured as non-owned because it has already been configured as a owned. Use the nested builder in `OwnsOne` or `OwnsMany` on the owner entity type builder to further configure this type. If you want to override previous configuration first remove the entity type from the model by calling 'Ignore'.
builder
.HasMany<Address>()
.WithOne(x => x.Tenant)
.HasForeignKey("tenant_id")
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);
// This is fine.
builder
.HasMany<Customer>()
.WithOne(x => x.Tenant)
.HasForeignKey("tenant_id")
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);

// This throws - System.InvalidOperationException: The entity type 'Address' cannot be configured as non-owned because it has already been configured as a owned. Use the nested builder in `OwnsOne` or `OwnsMany` on the owner entity type builder to further configure this type. If you want to override previous configuration first remove the entity type from the model by calling 'Ignore'.
builder
.HasMany<Address>()
.WithOne(x => x.Tenant)
.HasForeignKey("tenant_id")
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);
6 replies