dotnet/efcore

I want to customize what the dotnet scaffold generates

jvelezc opened this issue · 3 comments

Hello I need some guidance as to how to achieve the following expected result using scaffold
It is worth to note: #5617 was supposed to make it easier...

Actual Result

public partial class Food
{
     public int Id { get; set; }
     public string Name { get; set; }
     public string Description { get; set; }
     public double Price { get; set; }
}

Desired Result

public partial class Food : EntityBase
{
     public string Name { get; set; }
     public string Description { get; set; }
     public double Price { get; set; }
}

public class EntityBase : IEntityBase
{
    public int Id { get; set; }
}

My attempts:
Well first i tried the suggestion in this stack overflow post which is to use EntityTypeWritter. Except that class has been removed from this repo :).
https://stackoverflow.com/questions/40728223/entity-framework-core-customize-scaffolding/44520169#44520169

Then I tried to look at your source code and it seems that https://github.com/aspnet/EntityFrameworkCore/blob/f4c9f4c4be0e6f159506e583eda0ba68536356b2/src/EFCore.Design/Scaffolding/Internal/CSharpScaffoldingGenerator.cs
is responsible for scaffolding. From that class then
public class CSharpEntityTypeGenerator : ICSharpEntityTypeGenerator is invoked and here where I tried to override

public virtual string WriteCode(IEntityType entityType, string @namespace, bool useDataAnnotations)
      in which if you had made this method overridable i think i would have been able to do this 

       private void GenerateClass(IEntityType entityType)
       {
           if (_useDataAnnotations)
           {
               GenerateEntityTypeDataAnnotations(entityType);
           }

           _sb.AppendLine($"public partial class {entityType.Name}");

           _sb.AppendLine("{");

           using (_sb.Indent())
           {
               GenerateConstructor(entityType);
               GenerateProperties(entityType);
               GenerateNavigationProperties(entityType);
           }

           _sb.AppendLine("}");
       }

However , GenerateClass is private but if it was virtual then i would have easily been able to copy and paste the code below have the exact implementation except i can throw in there my EntityBaseClass.

    private void GenerateClass(IEntityType entityType)
    {
        if (_useDataAnnotations)
        {
            GenerateEntityTypeDataAnnotations(entityType);
        }

_sb.AppendLine($"public partial class {entityType.Name}+ ":EntityBase"");

        _sb.AppendLine("{");

        using (_sb.Indent())
        {
            GenerateConstructor(entityType);
            GenerateProperties(entityType);
            GenerateNavigationProperties(entityType);
        }

        _sb.AppendLine("}");
    }

how do you suggest i got about this.. re-write your whole class and register it with
public static void ConfigureDesignTimeServices(IServiceCollection services)
=> services.AddSingleton<CSharpEntityTypeGenerator, CustomCSharpEntityTypeGenerator>()

@jvelezc We agree this isn't great at the moment--there is an issue on the backlog (#4038) tracking this. We're still unsure of the best approach to take here--templating engine, lots of fine-grained methods to override, or something else. We didn't want to lock into something that wasn't what we ultimately decided to support, which is why these methods are private. That being said, we discussed in triage, and given that this is an internal class, we would accept a PR to add virtual methods here for the time being. The caveat is that because this is an internal class we may break it in a future release and any code you have that depends on it would need to be updated--possibly to something not very similar.

Closing as duplicate of #4038

Would love to be able to generate entity code with private setters, then create Update methods to update those fields in a partial class (DDD style).

(I'm stuck with scaffolding because my new EFCore project has to work with an ancient Linq2SQL database, and it's just not feasible to try to switch to running migrations.)

@simeyla would EF Core Power Tools with Handlebars templates be able to help you?