Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions entity-framework/core/cli/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Design-time services - EF Core
description: Information on Entity Framework Core design-time services
author: SamMonoRT
ms.date: 10/22/2020
ms.date: 01/17/2025
uid: core/cli/services
---
# Design-time services
Expand All @@ -11,14 +11,39 @@ Some services used by the tools are only used at design time. These services are

[!code-csharp[Main](../../../samples/core/Miscellaneous/CommandLine/DesignTimeServices.cs#DesignTimeServices)]

### Advanced customizations

You can override individual methods in design-time services. For example, to customize how type names are generated in scaffolded code, you can override the `ShouldUseFullName` method in `CSharpHelper`:

```csharp
public class MyDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection services)
=> services.AddSingleton<ICSharpHelper, MyCSharpHelper>();
}

public class MyCSharpHelper : CSharpHelper
{
public MyCSharpHelper(ITypeMappingSource typeMappingSource) : base(typeMappingSource)
{
}

public override bool ShouldUseFullName(Type type)
{
// Custom logic to determine when to use full type names
return base.ShouldUseFullName(type);
}
}
```

## Referencing Microsoft.EntityFrameworkCore.Design

Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This means that the dependency won't flow transitively into other projects, and that you cannot, by default, reference its types.

In order to reference its types and override design-time services, update the PackageReference item's metadata in your project file.

```xml
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.9">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<!-- Remove IncludeAssets to allow compiling against the assembly -->
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
Expand All @@ -34,20 +59,36 @@ The following is a list of the design-time services.
Service | Description
------------------------------------------------------------------------------------ | -----------
<xref:Microsoft.EntityFrameworkCore.Design.IAnnotationCodeGenerator> | Generates the code for corresponding model annotations.
<xref:Microsoft.EntityFrameworkCore.Design.ICandidateNamingService> | Generates candidate names for entities and properties.
<xref:Microsoft.EntityFrameworkCore.Design.ICSharpHelper> | Helps with generating C# code.
<xref:Microsoft.EntityFrameworkCore.Design.ICSharpMigrationOperationGenerator> | Generates C# code for migration operations.
<xref:Microsoft.EntityFrameworkCore.Design.ICSharpSnapshotGenerator> | Generates C# code for model snapshots.
<xref:Microsoft.EntityFrameworkCore.Design.ICSharpUtilities> | C# code generation utilities.
<xref:Microsoft.EntityFrameworkCore.Design.IPluralizer> | Pluralizes and singularizes words.
<xref:Microsoft.EntityFrameworkCore.Migrations.Design.IMigrationsCodeGenerator> | Generates code for a migration.
<xref:Microsoft.EntityFrameworkCore.Migrations.Design.IMigrationsCodeGeneratorSelector> | Selects the appropriate migrations code generator.
<xref:Microsoft.EntityFrameworkCore.Migrations.Design.IMigrationsScaffolder> | The main class for managing migration files.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.ICompiledModelCodeGenerator> | Generates code for compiled model metadata.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.ICompiledModelCodeGeneratorSelector> | Selects the appropriate compiled model code generator.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.ICompiledModelScaffolder> | The main class for scaffolding compiled models.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IDatabaseModelFactory> | Creates a database model from a database.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IModelCodeGenerator> | Generates code for a model.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IModelCodeGeneratorSelector> | Selects the appropriate model code generator.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IProviderConfigurationCodeGenerator> | Generates OnConfiguring code.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IReverseEngineerScaffolder> | The main class for scaffolding reverse engineered models.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IScaffoldingModelFactory> | Creates a model from a database model.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.IScaffoldingTypeMapper> | Maps database types to .NET types during scaffolding.
<xref:Microsoft.EntityFrameworkCore.Scaffolding.ISnapshotModelProcessor> | Processes model snapshots.
<xref:Microsoft.EntityFrameworkCore.Query.IPrecompiledQueryCodeGenerator> | Generates code for precompiled queries.
<xref:Microsoft.EntityFrameworkCore.Query.IPrecompiledQueryCodeGeneratorSelector> | Selects the appropriate precompiled query code generator.

## Using services

These services can also be useful for creating your own tools. For example, when you want to automate part of you design-time workflow.
These services can also be useful for creating your own tools. For example, when you want to automate part of your design-time workflow.

You can build a service provider containing these services using the AddEntityFrameworkDesignTimeServices and AddDbContextDesignTimeServices extension methods.

[!code-csharp[](../../../samples/core/Miscellaneous/CommandLine/CustomTools.cs#CustomTools)]

> [!NOTE]
> In EF Core 6.0 and later, the design-time services registration has been streamlined. The `AddEntityFrameworkDesignTimeServices()` method automatically registers all necessary design-time services, and `AddDbContextDesignTimeServices(context)` adds the DbContext-specific services from the provided context instance.
2 changes: 1 addition & 1 deletion entity-framework/core/miscellaneous/internals/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ In a nutshell, here are some of the strategies it uses.

### Design-time services

In addition to the application services and the internal DbContext services, there is a third set of [design-time services](xref:core/cli/services). These aren't added to internal service provider since they're never needed at runtime. The design-time services are built by [DesignTimeServicesBuilder](https://github.com/dotnet/efcore/blob/main/src/EFCore.Design/Design/Internal/DesignTimeServicesBuilder.cs). There are two main path--one with a context instance and one without. The one without is primarily used when scaffolding a new DbContext. There are several extensibility points here to allow the user, providers, and extensions to override and customize the services.
In addition to the application services and the internal DbContext services, there is a third set of [design-time services](xref:core/cli/services). These aren't added to internal service provider since they're never needed at runtime. The design-time services are built by [DesignTimeServicesBuilder](https://github.com/dotnet/efcore/blob/main/src/EFCore.Design/Design/Internal/DesignTimeServicesBuilder.cs). There are two main paths--one with a context instance and one without. The one without is primarily used when scaffolding a new DbContext. There are several extensibility points here to allow the user, providers, and extensions to override and customize the services.

The user can customize services by adding an implementation of `IDesignTimeServices` to the startup assembly.

Expand Down
24 changes: 21 additions & 3 deletions samples/core/Miscellaneous/CommandLine/CustomTools.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -12,19 +13,24 @@ public static void AddMigration(string migrationName)
{
var projectDir = Directory.GetCurrentDirectory();
var rootNamespace = "ConsoleApp1";
var outputDir = "Migraitons";
var outputDir = "Migrations";

#region CustomTools
var db = new MyDbContext();
using var db = new MyDbContext();

// Create design-time services
var serviceCollection = new ServiceCollection();

// Add the core design-time services
serviceCollection.AddEntityFrameworkDesignTimeServices();

// Add services from the DbContext
serviceCollection.AddDbContextDesignTimeServices(db);

var serviceProvider = serviceCollection.BuildServiceProvider();

// Add a migration
var migrationsScaffolder = serviceProvider.GetService<IMigrationsScaffolder>();
var migrationsScaffolder = serviceProvider.GetRequiredService<IMigrationsScaffolder>();
var migration = migrationsScaffolder.ScaffoldMigration(migrationName, rootNamespace);
migrationsScaffolder.Save(projectDir, migration, outputDir);
#endregion
Expand All @@ -33,4 +39,16 @@ public static void AddMigration(string migrationName)

internal class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=MyDatabase;Trusted_Connection=true;");
}

public DbSet<Blog> Blogs { get; set; }
}

internal class Blog
{
public int Id { get; set; }
public string Title { get; set; }
}