Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 16 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 @@ -18,7 +18,7 @@ Microsoft.EntityFrameworkCore.Design is a DevelopmentDependency package. This me
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="9.0.0">
<PrivateAssets>all</PrivateAssets>
<!-- Remove IncludeAssets to allow compiling against the assembly -->
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
Expand All @@ -34,19 +34,32 @@ 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.

Expand Down
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
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ Because of these limitations, you should only use compiled models if your EF Cor

If supporting any of these features is critical to your success, then please vote for the appropriate issues linked above.

### Handling compilation errors due to ambiguous type references

When compiling models with types that have the same name but exist in different namespaces, the generated code may produce compilation errors due to ambiguous type references. To resolve this, you can customize the code generation to use fully-qualified type names by overriding `CSharpHelper.ShouldUseFullName` to return `true`. See [Design-time services](xref:core/cli/services) for information on how to override design-time services like `ICSharpHelper`.

## Reducing runtime overhead

As with any layer, EF Core adds a bit of runtime overhead compared to coding directly against lower-level database APIs. This runtime overhead is unlikely to impact most real-world applications in a significant way; the other topics in this performance guide, such as query efficiency, index usage and minimizing roundtrips, are far more important. In addition, even for highly-optimized applications, network latency and database I/O will usually dominate any time spent inside EF Core itself. However, for high-performance, low-latency applications where every bit of perf is important, the following recommendations can be used to reduce EF Core overhead to a minimum:
Expand Down
34 changes: 29 additions & 5 deletions samples/core/Miscellaneous/CommandLine/CustomTools.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System.IO;
using System;
using System.IO;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;

namespace CommandLine;
Expand All @@ -12,19 +16,27 @@ 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();
serviceCollection.AddEntityFrameworkDesignTimeServices();
serviceCollection.AddDbContextDesignTimeServices(db);

var provider = db.GetService<IDatabaseProvider>().Name;
var providerAssembly = Assembly.Load(new AssemblyName(provider));
var providerServicesAttribute = providerAssembly.GetCustomAttribute<DesignTimeProviderServicesAttribute>();
var designTimeServicesType = providerAssembly.GetType(providerServicesAttribute.TypeName, throwOnError: true);
((IDesignTimeServices)Activator.CreateInstance(designTimeServicesType)!).ConfigureDesignTimeServices(serviceCollection);

serviceCollection.AddEntityFrameworkDesignTimeServices();

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 +45,16 @@ public static void AddMigration(string migrationName)

internal class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(@"Data Source=test.db");
}

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

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