Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use different kind of configuration than attributes #15

Closed
Burgyn opened this issue May 22, 2019 · 2 comments · Fixed by #18
Closed

Use different kind of configuration than attributes #15

Burgyn opened this issue May 22, 2019 · 2 comments · Fixed by #18
Assignees
Labels
api-suggestion enhancement New feature or request
Milestone

Comments

@Burgyn
Copy link
Member

Burgyn commented May 22, 2019

Starting discussion about Use different kind of configuration than attributes from #8.

Current state

Now some configuration is allowed only using attributes (Key, Alias). Something can be changed using custom ModelMapper.

[Alias("Foo")]
public class Foo
{
    [Key("PK_Foo", AutoIncrementMethodType.Identity)]
    public int Id { get; set; }

    [Alias("Name")]
    public string FirstName { get; set; }

    [NoMap]
    public string LastName { get; set; }

    [Converter(typeof(AddressConverter))]
    public IEnumerable<string> Addresses { get; set; }

    [NoMap]
    public IEmailService EmailService { get; set; }
}

Available attributes:

  • Alias - Define name for database object (table, column).
  • Key - Define primary key for table.
  • NoMap - When property is mark with this attribute, then KORM ignore this column.
  • Converter - Define converter for converting values between database and CLR.

When want use property injection, we must use ModelMapper:

Database.DefaultModelMapper
    .InjectionConfigurator<Foo>()
        .FillProperty(p => p.EmailService, () => new EmailService());

In many scenarios it's OK. However, there are scenarios where we want to have a model definition and mapping it to a database separate. For example, if you want to have entities in domain layer and mapping in infrastructure layer.

Design

The proposal is based on how it is in EF. Have a configuration class where, we are fluent define model mapping to database.

public class DatabaseConfiguration: DatabaseConfigurationBase
{
    public override void OnModelCreating(ModelConfigurationBuilder modelBuilder)
    {
        modelBuilder.Entity<Foo>()
            .HasTableName("Foo")
            .HasPrimaryKey(f => f.Id)
                .HasAutoIncrementMethodType(AutoIncrementMethodType.Identity)
                .HasConstraintName("PK_Foo")
                .Entity
            .Property(f => f.FirstName)
                .HasColumnName("Name")
                .Entity
            .Property(f => f.LastName)
                .NoMap()
                .Entity
            .Property(f => f.Addresses)
                .HasConverter<AddressConverter>()
                .Entity
            .Property(f => f.EmailService)
                .FillProperty(() => new EmailService());
    }
}

Uses in ASP.NET Core applications:

public void ConfigureServices(IServiceCollection services)
{
  services.AddKorm(Configuration)
	.AddKormMigrations(Configuration)
        .UseDatabaseConfiguration<DatabaseCofiguration>()
	.Migrate();
}

Implementation

I tried to explore it.
It is possible implemented into KORM.

@Burgyn
Copy link
Member Author

Burgyn commented May 24, 2019

After the discussion with @satano, we propose the following convention:

public class DatabaseConfiguration: DatabaseConfigurationBase
{
    public override void OnModelCreating(ModelConfigurationBuilder modelBuilder)
    {
        modelBuilder.Entity<Foo>()
            .HasTableName("Foo")
            .HasPrimaryKey(f => f.Id)
                .WithName("PK_Foo")
                .AutoIncrement(AutoIncrementMethodType.Custom)
            .Property(f => f.FirstName).HasColumnName("Name")
            .Property(f => f.LastName).NoMap()
            .Property(f => f.Addresses).UseConverter<AddressConverter>()
            .Property(f => f.EmailService).InjectValue(() => new EmailService());
    }
}

@Burgyn
Copy link
Member Author

Burgyn commented May 29, 2019

I'm starting to work on it. You're OK with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants