EntityFramework.Docs icon indicating copy to clipboard operation
EntityFramework.Docs copied to clipboard

Design-time services documentation out of date

Open iplusMario opened this issue 3 years ago • 6 comments

[Enter feedback here] This documentation is out of date. In net 6.0 this line var migrationsScaffolder = serviceProvider.GetService<IMigrationsScaffolder>() throws error.

See https://github.com/dotnet/efcore/issues/23595


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

iplusMario avatar Sep 05 '22 07:09 iplusMario

I ran into this same issue when trying to use https://github.com/dotnet/efcore/issues/23595 with <TargetFramework>net6.0</TargetFramework> and
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.6">

I was able to get it working by adding the following registrations before calling BuildServiceProvider:

        var serviceCollection = new ServiceCollection();
        serviceCollection.AddEntityFrameworkDesignTimeServices();
        serviceCollection.AddDbContextDesignTimeServices(context);
       
        // these additional registrations were needed on dotnet 6.0 
        serviceCollection.AddScoped<AnnotationCodeGeneratorDependencies>();
        serviceCollection.AddScoped<TypeMappingSourceDependencies>();
        serviceCollection.AddScoped<ValueConverterSelectorDependencies>();
        serviceCollection.AddScoped<RelationalTypeMappingSourceDependencies>();
        serviceCollection.AddSingleton<IValueConverterSelector, ValueConverterSelector>();
        serviceCollection.AddSingleton<ITypeMappingSource, SqlServerTypeMappingSource>();
        serviceCollection.AddSingleton<IAnnotationCodeGenerator, SqlServerAnnotationCodeGenerator>();
        
        var serviceProvider = serviceCollection.BuildServiceProvider();
        var migrationsScaffolder = serviceProvider.GetRequiredService<IMigrationsScaffolder>();

wiggins-twentyideas avatar Sep 06 '22 14:09 wiggins-twentyideas

@AndriySvyryd Did these APIs break? Do they need to be called in a different order? Is an additional call needed on the service collectoin?

bricelam avatar Sep 06 '22 17:09 bricelam

@wiggins-twentyideas there is another way see https://github.com/dotnet/efcore/issues/23595#issuecomment-966185003

@bricelam yes API did break. In net5.0 configuring design time service was not required.

iplusMario avatar Sep 07 '22 06:09 iplusMario

Now we don't add redundant relational-level services. Provider services always need to be added as they might have different implementation.

var provider = context.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);

AndriySvyryd avatar Sep 07 '22 21:09 AndriySvyryd

Previously, this line was responsible for resolving the provider-specific services:

serviceCollection.AddDbContextDesignTimeServices(context);

bricelam avatar Oct 11 '22 18:10 bricelam

See also https://github.com/dotnet/efcore/issues/27502

ajcvickers avatar Jan 04 '24 09:01 ajcvickers