diff --git a/src/Detached.Mappers.EntityFramework/Detached.Mappers.EntityFramework.csproj b/src/Detached.Mappers.EntityFramework/Detached.Mappers.EntityFramework.csproj index 633dd3f..204a168 100644 --- a/src/Detached.Mappers.EntityFramework/Detached.Mappers.EntityFramework.csproj +++ b/src/Detached.Mappers.EntityFramework/Detached.Mappers.EntityFramework.csproj @@ -4,6 +4,7 @@ net6.0;net8.0;net9.0 enable enable + 13 diff --git a/src/Detached.Mappers.EntityFramework/Options/DelegateMapperConfiguration.cs b/src/Detached.Mappers.EntityFramework/Options/DelegateMapperConfiguration.cs new file mode 100644 index 0000000..6c7de37 --- /dev/null +++ b/src/Detached.Mappers.EntityFramework/Options/DelegateMapperConfiguration.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; + +namespace Detached.Mappers.EntityFramework.Options +{ + public class DelegateMapperConfiguration(Action config) : IMapperConfiguration + where TDbContext : DbContext + { + public void ConfigureMapper(EntityMapperOptionsBuilder mapper) + { + config(mapper); + } + } +} diff --git a/src/Detached.Mappers.EntityFramework/Options/IMapperConfiguration.cs b/src/Detached.Mappers.EntityFramework/Options/IMapperConfiguration.cs new file mode 100644 index 0000000..7766329 --- /dev/null +++ b/src/Detached.Mappers.EntityFramework/Options/IMapperConfiguration.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; + +namespace Detached.Mappers.EntityFramework.Options +{ + public interface IMapperConfiguration + { + void ConfigureMapper(EntityMapperOptionsBuilder mapper); + } + + public interface IMapperConfiguration : IMapperConfiguration + where TDbContext : DbContext + { + } +} \ No newline at end of file diff --git a/src/Detached.Mappers.EntityFramework/Package.cs b/src/Detached.Mappers.EntityFramework/Package.cs index fb63956..560d287 100644 --- a/src/Detached.Mappers.EntityFramework/Package.cs +++ b/src/Detached.Mappers.EntityFramework/Package.cs @@ -2,17 +2,17 @@ using Detached.Mappers.EntityFramework.Options; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using System; +using Microsoft.Extensions.DependencyInjection; namespace Detached.Mappers.EntityFramework { public static class Package { - public static DbContextOptionsBuilder UseMapping(this DbContextOptionsBuilder dbContextBuilder, Action configure = null) + public static DbContextOptionsBuilder UseMapping(this DbContextOptionsBuilder dbContextBuilder, Action? configure = null) { var options = new EntityMapperOptions(); - configure?.Invoke(options); + configure?.Invoke(new EntityMapperOptionsBuilder()); UseMapping(dbContextBuilder, options); @@ -27,5 +27,28 @@ public static DbContextOptionsBuilder UseMapping(this DbContextOptionsBuilder db return dbContextBuilder; } + + public static DbContextOptionsBuilder UseMapping(this DbContextOptionsBuilder dbContextBuilder, IServiceProvider serviceProvider) + { + var builder = new EntityMapperOptionsBuilder(); + + var configType = typeof(IMapperConfiguration<>).MakeGenericType(dbContextBuilder.Options.ContextType); + + foreach (IMapperConfiguration? configService in serviceProvider.GetServices(configType)) + { + configService?.ConfigureMapper(builder); + } + + UseMapping(dbContextBuilder, builder.Options); + + return dbContextBuilder; + } + + public static IServiceCollection ConfigureMapper(this IServiceCollection services, Action config) + where TDbContext : DbContext + { + services.AddTransient>(sp => new DelegateMapperConfiguration(config)); + return services; + } } } \ No newline at end of file diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureCustomMapper.cs b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureCustomMapperTests.cs similarity index 96% rename from test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureCustomMapper.cs rename to test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureCustomMapperTests.cs index e1c88c5..565a7a8 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureCustomMapper.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureCustomMapperTests.cs @@ -10,9 +10,9 @@ using System.Threading.Tasks; using Xunit; -namespace Detached.Mappers.EntityFramework.Tests.Features +namespace Detached.Mappers.EntityFramework.Tests.Configuration { - public class ConfigureCustomMapper + public class ConfigureCustomMapperTests { [Fact] public async Task configure_custom_mapper() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureFromServicesTests.cs b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureFromServicesTests.cs new file mode 100644 index 0000000..818efb2 --- /dev/null +++ b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureFromServicesTests.cs @@ -0,0 +1,69 @@ +using Detached.Mappers.Annotations.Extensions; +using Detached.Mappers.EntityFramework.Extensions; +using Detached.Mappers.EntityFramework.Tests.Fixture; +using Detached.Mappers.Types; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Detached.Mappers.EntityFramework.Tests.Configuration +{ + public class ConfigureFromServicesTests + { + [Fact] + public void configure_mapper_from_services() + { + var services = new ServiceCollection(); + + services.AddDbContext((services, db) => + { + db.UseSqlite($"DataSource=file:{nameof(configure_mapper_from_services)}?mode=memory&cache=shared"); + db.UseMapping(services); + }); + + + services.ConfigureMapper(builder => + { + builder.Type().Entity(true); + builder.Type().Member(c => c.CustomizedKey1).Key(true); + builder.Type().Member(c => c.CustomizedKey2).Key(true); + builder.Type().Key(c => c.CustomizedKey1, c => c.CustomizedKey2); + }); + + var serviceProvider = services.BuildServiceProvider(); + + var dbContext = serviceProvider.GetRequiredService(); + + IType typeOptions = dbContext.GetMapper().Options.GetType(typeof(ModuleTestClass)); + + Assert.True(typeOptions.IsEntity()); + Assert.True(typeOptions.GetMember(nameof(ModuleTestClass.CustomizedKey1)).IsKey()); + Assert.True(typeOptions.GetMember(nameof(ModuleTestClass.CustomizedKey2)).IsKey()); + Assert.False(typeOptions.GetMember(nameof(ModuleTestClass.Id)).IsKey()); + } + } + + public class ModuleTestClass + { + public int Id { get; set; } + + public int CustomizedKey1 { get; set; } + + public int CustomizedKey2 { get; set; } + + public string Name { get; set; } + } + + public class ModuleTestDbContext : TestDbContext + { + public ModuleTestDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder mb) + { + mb.Entity().HasKey(c => new { c.CustomizedKey1, c.CustomizedKey2 }); + } + } +} diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureProfiles.cs b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureProfilesTests.cs similarity index 96% rename from test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureProfiles.cs rename to test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureProfilesTests.cs index 91e6135..cf5d81d 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureProfiles.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureProfilesTests.cs @@ -8,9 +8,9 @@ using System.Threading.Tasks; using Xunit; -namespace Detached.Mappers.EntityFramework.Tests.Features +namespace Detached.Mappers.EntityFramework.Tests.Configuration { - public class ConfigureProfiles + public class ConfigureProfilesTests { [Fact] public async Task configure_profiles_profile1() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureTypeFluent.cs b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureTypeFluentTests.cs similarity index 95% rename from test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureTypeFluent.cs rename to test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureTypeFluentTests.cs index 5cd8773..390763a 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/ConfigureTypeFluent.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Configuration/ConfigureTypeFluentTests.cs @@ -7,9 +7,9 @@ using System.Threading.Tasks; using Xunit; -namespace Detached.Mappers.EntityFramework.Tests.Features +namespace Detached.Mappers.EntityFramework.Tests.Configuration { - public class ConfigureTypeFluent + public class ConfigureTypeFluentTests { [Fact] public async Task apply_conventions_to_fluent() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociationIList.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/AssociationIListTests.cs similarity index 97% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociationIList.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/AssociationIListTests.cs index e096e81..56db44c 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociationIList.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/AssociationIListTests.cs @@ -9,7 +9,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapAssociationIList + public class AssociationIListTests { [Fact] public async Task map_association_ilist() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociationNoSetter.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/AssociationNoSetterTests.cs similarity index 97% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociationNoSetter.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/AssociationNoSetterTests.cs index 257fe3b..6016808 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociationNoSetter.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/AssociationNoSetterTests.cs @@ -9,7 +9,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapAssociationNoSetter + public class AssociationNoSetterTests { [Fact] public async Task map_association_nosetter() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociation.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/AssociationTests.cs similarity index 99% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociation.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/AssociationTests.cs index 3247955..bfce619 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapAssociation.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/AssociationTests.cs @@ -14,7 +14,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapAssociation + public class AssociationTests { [Fact] public async Task map_association() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapMany.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/BatchTests.cs similarity index 98% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapMany.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/BatchTests.cs index 447f09a..c1a4129 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapMany.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/BatchTests.cs @@ -14,7 +14,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapMany + public class BatchTests { [Fact] public async Task map_many() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/BindForeingKeyToDto.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/BindForeingKeyToDtoTests.cs similarity index 100% rename from test/Detached.Mappers.EntityFramework.Tests/Features/BindForeingKeyToDto.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/BindForeingKeyToDtoTests.cs diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapDtoToEntity.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/DtoToEntityTests.cs similarity index 99% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapDtoToEntity.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/DtoToEntityTests.cs index 7d19557..ff3c1fe 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapDtoToEntity.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/DtoToEntityTests.cs @@ -14,7 +14,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapDtoToEntity + public class DtoToEntityTests { [Fact] public async Task map_dto_to_entity() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapEntityNoKey.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/EntityNoKeyTests.cs similarity index 99% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapEntityNoKey.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/EntityNoKeyTests.cs index 48910f6..25f6bb3 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapEntityNoKey.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/EntityNoKeyTests.cs @@ -13,7 +13,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapEntityNoKey + public class EntityNoKeyTests { [Fact] public async Task map_entity_nokey_dto() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapEntityNullableKey.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/EntityNullableKeyTests.cs similarity index 97% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapEntityNullableKey.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/EntityNullableKeyTests.cs index dc1a75b..d5f0f90 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapEntityNullableKey.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/EntityNullableKeyTests.cs @@ -8,7 +8,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapEntityNullableKey + public class EntityNullableKeyTests { [Fact] public async Task map_entity_nullable_key() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapForeignKeyLongNameToEntity.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/ForeignKeyLongNameToEntityTests.cs similarity index 97% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapForeignKeyLongNameToEntity.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/ForeignKeyLongNameToEntityTests.cs index 1753ae6..fecee93 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapForeignKeyLongNameToEntity.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/ForeignKeyLongNameToEntityTests.cs @@ -9,7 +9,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapForeignKeyLongNameToEntity + public class ForeignKeyLongNameToEntityTests { [Fact] public async Task map_fk_longname_to_entity() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapForeignKeyToEntity.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/ForeignKeyToEntityTests.cs similarity index 98% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapForeignKeyToEntity.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/ForeignKeyToEntityTests.cs index a9a94b0..e74ed80 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapForeignKeyToEntity.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/ForeignKeyToEntityTests.cs @@ -8,7 +8,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapForeignKeyToEntity + public class ForeignKeyToEntityTests { [Fact] public async Task map_fk_to_entity() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/InputTests.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/FullGraphTests.cs similarity index 99% rename from test/Detached.Mappers.EntityFramework.Tests/Features/InputTests.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/FullGraphTests.cs index 329f3c1..2ced215 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/InputTests.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/FullGraphTests.cs @@ -14,7 +14,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class InputTests + public class FullGraphTests { [Fact] public async Task map_input() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/ImportJson.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/ImportJsonTests.cs similarity index 99% rename from test/Detached.Mappers.EntityFramework.Tests/Features/ImportJson.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/ImportJsonTests.cs index 79ca154..56dccbc 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/ImportJson.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/ImportJsonTests.cs @@ -15,7 +15,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class ImportJson + public class ImportJsonTests { [Fact] public async Task map_json_string() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapInheritedEntity.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/InheritedEntityTests.cs similarity index 99% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapInheritedEntity.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/InheritedEntityTests.cs index 8c8f889..fa8dac4 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapInheritedEntity.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/InheritedEntityTests.cs @@ -13,7 +13,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapInheritedEntity + public class InheritedEntityTests { [Fact] public async Task map_inherited_entity() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapMemberWithValueConverter.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/MemberWithValueConverterTests.cs similarity index 98% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapMemberWithValueConverter.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/MemberWithValueConverterTests.cs index 227afd2..dae2e5f 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapMemberWithValueConverter.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/MemberWithValueConverterTests.cs @@ -14,7 +14,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapMemberWithValueConverter + public class MemberWithValueConverterTests { [Fact] public async Task map_meber_with_value_converter() diff --git a/test/Detached.Mappers.EntityFramework.Tests/Features/MapOwnedEntity.cs b/test/Detached.Mappers.EntityFramework.Tests/Features/OwnedEntityTests.cs similarity index 98% rename from test/Detached.Mappers.EntityFramework.Tests/Features/MapOwnedEntity.cs rename to test/Detached.Mappers.EntityFramework.Tests/Features/OwnedEntityTests.cs index 9aa1c76..5148472 100644 --- a/test/Detached.Mappers.EntityFramework.Tests/Features/MapOwnedEntity.cs +++ b/test/Detached.Mappers.EntityFramework.Tests/Features/OwnedEntityTests.cs @@ -11,7 +11,7 @@ namespace Detached.Mappers.EntityFramework.Tests.Features { - public class MapOwnedEntity + public class OwnedEntityTests { [Fact] public async Task map_owned_entity()