TrackableEntities / EntityFrameworkCore.Scaffolding.Handlebars

Scaffold EF Core models using Handlebars templates.
MIT License
210 stars 53 forks source link

Easier custom renaming of entities and properties #34

Closed Vizehase closed 5 years ago

Vizehase commented 6 years ago

I have written Handlebars helpers for our special naming conventions. It turned out that renaming the navigation properties was pretty hard because I had to split the pregenerated names and repeat the renaming on the individual parts of the name. A feature for giving two conversion methods would be very handy such as string CreatePropertyName(string) which takes the original field name (e.g "c_first_name") and delivers the desired property name to use in the entity class (e.g. "FirstName"). Likewise a method string CreateEntityClassName(string) that does the naming for entity types. Maybe an interface with these two methods could be created and this service would be used by Handlebars when it finds this service (also taken into account when generating names for navigation properties). And: I did the custom renaming of the entity types with my Handlebars helper, but the file name was not affected; how can this be accomplished?

tonysneed commented 5 years ago

@Vizehase Thanks for your question. Again, I apologize for having missed it. To open up the entity conversion process, I could create an IEntityTypeTransformationService interface with an HbsEntityTypeTransformationService implementation that just returns the given input. I could then refactor the AddHandlebarsScaffolding method to accept an optional parameter for the conversion service.

To answer your second question, the file naming is performed in HbsCSharpModelGenerator and is based simply on IEntityType. We would just need to inject IEntityTypeTransformationService into that class and call the same method to get the class name.

tonysneed commented 5 years ago

Resolved by #47.

tonysneed commented 5 years ago

This is included in v1.7.1. Please re-open this issue if you have further questions.

dharmaturtle commented 5 years ago

I wanted to append "Entity" to my entity's type names, so here's the code I used for that.

  public class MyDesignTimeServices : IDesignTimeServices {
    public void ConfigureDesignTimeServices(IServiceCollection services) {
      services.AddHandlebarsScaffolding();
      services.AddHandlebarsTransformers(
        entityNameTransformer: x => x + "Entity",
        entityFileNameTransformer: x => x + "Entity",
        constructorTransformer: x => {
          x.PropertyType += "Entity";
          return x;
        },
        navPropertyTransformer: x => {
          x.PropertyType += "Entity";
          return x;
        });
    }
  }
j-childers commented 4 years ago

I noticed a couple of places that might have been missed when implementing the renaming features. It may be that I don't understand the code well enough at this point, though. So here goes...

In HbsCSharpDbContextGenerator.GenerateDbSets, the property name is assigned by calling GetDbSetName(), which will return the underlying name that was generated by EF Core. If someone has renamed their entities, this name is likely to be "wrong" (although it should still build successfully) - or at least in a format that doesn't conform to their renaming.

It would be nice to either use the renamed entity name here, or to give the developer a way to hook into the property name assigned to the DbSets, and rename it themselves.

Similar comment on HbsCSharpEntityTypeGenerator.GenerateNavigationProperties, which uses calls INavigaion.GetTargetType(), and doesn't run the result through the entity name transformation. If you've renamed that entity, the navigation property will be incorrect, and the resulting code doesn't build.