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

Fluent API: support like EF IEntityTypeConfiguration for seperate domain entity #14

Closed
a-patel opened this issue Mar 17, 2018 · 16 comments

Comments

@a-patel
Copy link
Collaborator

a-patel commented Mar 17, 2018

I do not want to change the domain entities using a decorator.
I want something like this,

            //dynamically load all configuration
            //System.Type configType = typeof(LanguageMap);   //any of your configuration classes here

            var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
            .Where(type => !string.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
                type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.ApplyConfiguration(configurationInstance);
            }
            //...or do it manually below. For example,
            //modelBuilder.Configurations.Add(new LanguageMap());
@a-patel
Copy link
Collaborator Author

a-patel commented Mar 17, 2018

@Biarity
Copy link
Owner

Biarity commented Mar 17, 2018

Fluent API is already supported: #4 (comment)

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 17, 2018

I know Fluent API is supported already.
I want to load/register Fluent API for particular domain dynamically.
e.g. find base class or interface implementation in assemblies.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 17, 2018

I have also looked into the pull request,
https://github.com/tflanitzer/Sieve/tree/explicit-properties

I want similar that kind of approach, but not in controller.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 17, 2018

public partial class BlogPostMap : IEntityTypeConfiguration<BlogPost>
    {
        public override void Configure(EntityTypeBuilder<BlogPost> builder)
        {
            base.Configure(builder);
            builder.ToTable("BlogPost");
            builder.HasKey(bp => bp.Id);
            builder.Property(bp => bp.Title).IsRequired();
            builder.Property(bp => bp.Body).IsRequired().HasMaxLength(400);
        }
    }

I am asking for such functionality.
So one can find the IEntityTypeConfiguration implementation in other assembly and load them dynamically.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 17, 2018

This is just suggestion,
#Good to Have feature.

@Biarity
Copy link
Owner

Biarity commented Mar 17, 2018

What if you create multiple subclasses with different fluent APIs then use something like DI to choose the one you want to be used?

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 18, 2018

It will be great if you can give me an example code.
Thank you in advance.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 20, 2018

any update?

@Biarity
Copy link
Owner

Biarity commented Mar 21, 2018

Sorr for the delay - I meant creating multiple subclasses of SieveProcessor (instead of just the 1 as you'd do for the fluent API normally). Then you'd be able to manually choose which implementation to use.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 21, 2018

then how to register 'SieveProcessor'?
It will be very very helpful, if you can give an example.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 21, 2018

Basically I want new change in core functionality,
I need to find all classes which implemented one base class/interface (i.e. IEntityTypeConfiguration in EF API) in particular assembly(es),
and register such classes in SieveProcessor.

Hope you understand my requirement.

@a-patel
Copy link
Collaborator Author

a-patel commented Mar 24, 2018

please do the needful.
thank you

@Biarity
Copy link
Owner

Biarity commented Mar 25, 2018

Creating multiple subclasses looks like:

public class ApplicationSieveProcessorOne : SieveProcessor
{
    public ApplicationSieveProcessor(
        IOptions<SieveOptions> options, 
        ISieveCustomSortMethods customSortMethods, 
        ISieveCustomFilterMethods customFilterMethods) 
        : base(options, customSortMethods, customFilterMethods)
    {
    }

    protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
    {
      //mapper details from issue #4
    }
}

and another one

public class ApplicationSieveProcessorTwo : SieveProcessor
{
    public ApplicationSieveProcessor(
        IOptions<SieveOptions> options, 
        ISieveCustomSortMethods customSortMethods, 
        ISieveCustomFilterMethods customFilterMethods) 
        : base(options, customSortMethods, customFilterMethods)
    {
    }

    protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
    {
      //DIFFERENT mapper details from issue #4
    }
}

Now just use whichever class you want. I'm not really sure why this wouldn't work for ya. Are you using it with ASP.NET Core and the default DI? If so, you can easily inject whichever class you want in Startup.cs.

@Biarity Biarity closed this as completed Apr 6, 2018
@Dzivo
Copy link

Dzivo commented Nov 18, 2019

I dont aggree with you @Biarity this is very inefective.

EF Core enables us to use builder from our models without any other setup you just need to implement interface. This should't be that hard to implement since you already have SieveProcessor.

If you would like i can make a pull request but only if you are interested in such a feature :)

@Dzivo
Copy link

Dzivo commented Nov 18, 2019

For now i use something like this

public class MyEntity : ISieveConfiguration
{
  public string Name { get; set; }

  public void ConfigureSieve(SievePropertyMapper mapper)
  {
    mapper.Property<Regatta>(p => p.Name)
      .CanFilter();
  }
}

public interface ISieveConfiguration
{
  public void ConfigureSieve(SievePropertyMapper mapper);
}

public class CustomSieveProcessor : SieveProcessor
{
    public CustomSieveProcessor(
        IOptions<SieveOptions> options)
        : base(options)
    {
    }

    protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
    {
      Assembly
        .GetExecutingAssembly()
        .GetTypes()
        .Where(m => m.GetInterfaces().Any(i => i == typeof(ISieveConfiguration)))
        .ToList()
        .ForEach(m =>
        {
          var instance = Activator.CreateInstance(m);
          m.GetMethod("ConfigureSieve").Invoke(m, new object[] { mapper });
        });

      return mapper;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants