Search code examples
c#.netentity-frameworkmigrationcrud

An error occurred while accessing the Microsoft.Extensions.Hosting services when do first migrations


I don't understand what wrong. I tried to make a simple crud in .net core mvc with a very simple model which has few fields.

These are my models:

    public class Employee
    {
        [Key] public int EmployeeId { get; set; }

        [Required] public string FistName { get; set; }

        [Required] public string LastName { get; set; }

        public int PositionId { get; set; }
        public virtual Position Position { get; set; }

    }
public class Position
    {
        [Key]
        public int PositionId { get; set; }
        public string PositionName { get; set; }
        public ICollection<Employee> Employees { get; set; }
    }

then I made app context:

public class EmployeeContext : DbContext
{
    public EmployeeContext(DbContextOptions<EmployeeContext> options)
        : base(options)
    {
    }

    public DbSet<Employee> Employees { get; set; }
    public DbSet<Position> Positions { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>()
            .HasOne(e => e.Position)
            .WithMany()
            .HasForeignKey(e => e.PositionId);
    }
}

and registered context in Startup.cs:

 public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDbContext<EmployeeContext>(item =>item.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);                
        }

may be need one more file code of .csproj and program.cs

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net461</TargetFramework>
    <DebugType>full</DebugType>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.2.8" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.6" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="3.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
  </ItemGroup>

</Project>

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }

then I tried to do first migrate, but I see a very strange error Add-Migration FirstInit -verbose

Using project 'Crud'.
Using startup project 'Crud'.
Build started...
Build succeeded.
C:\.nuget\packages\microsoft.entityframeworkcore.tools\3.1.2\tools\net461\win-x86\ef.exe migrations add FirstInit --json --verbose --no-color --prefix-output --assembly C:\source\repos\Crud\Crud\bin\Debug\net461\Crud.exe --startup-assembly C:\source\repos\Crud\Crud\bin\Debug\net461\Crud.exe --project-dir C:\source\repos\Crud\Crud\ --language C# --working-dir C:\source\repos\Crud --root-namespace Crud
Using assembly 'Crud'.
Using startup assembly 'Crud'.
Using application base 'C:\source\repos\Crud\Crud\bin\Debug\net461'.
Using working directory 'C:\source\repos\Crud\Crud'.
Using root namespace 'Crud'.
Using project directory 'C:\source\repos\Crud\Crud\'.
Using configuration file 'C:\source\repos\Crud\Crud\bin\Debug\net461\Crud.exe.config'.
Using assembly 'Crud'.
Using startup assembly 'Crud'.
Using application base 'C:\source\repos\Crud\Crud\bin\Debug\net461'.
Using working directory 'C:\source\repos\Crud\Crud'.
Using root namespace 'Crud'.
Using project directory 'C:\source\repos\Crud\Crud\'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding Microsoft.Extensions.Hosting service provider...
Using environment 'Development'.
System.TypeLoadException: There is no implementation of the GetItem method in the type "Microsoft.AspNetCore.Mvc.Razor.Internal.FileProviderRazorProjectFileSystem" from assembly "Microsoft.AspNetCore.Mvc.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
   в Microsoft.Extensions.DependencyInjection.MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngineServices(IServiceCollection services)
   в Microsoft.Extensions.DependencyInjection.MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngine(IMvcCoreBuilder builder)
   в Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddMvc(IServiceCollection services)
   в Crud.Startup.ConfigureServices(IServiceCollection services) в C:\source\repos\Crud\Crud\Startup.cs:строка 38
--- End the stack trace from the previous location where the exception occurred ---
   в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   в Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
   в Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
   в Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
   в Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider. Error: There is no implementation of the GetItem method in the type "Microsoft.AspNetCore.Mvc.Razor.Internal.FileProviderRazorProjectFileSystem" from assembly "Microsoft.AspNetCore.Mvc.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'EmployeeContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'EmployeeContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728 ---> System.MissingMethodException:There are no parameterless constructors defined for this object..
   в System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   в System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   в System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   в System.Activator.CreateInstance(Type type, Boolean nonPublic)
   в System.Activator.CreateInstance(Type type)
   в Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_3.<FindContextTypes>b__13()
   --- End trace of internal exception stack ---
   в Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_3.<FindContextTypes>b__13()
   в Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   в Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   в Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   в Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   в Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   в Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   в Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to create an object of type 'EmployeeContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

What's wrong with these 3 lines?


Solution

  • Important: This will occur when a service or dependency can't be resolved. Run your code in debug mode or you can see what is missing using -verbose with your migration command. If you can resolve dependencies and run the code without errors, you can proceed with the migrations. However, if you can't do that or want to run migrations separately from the app logic, please follow the instructions.

    EF calls CreateWebHostBuilder or BuildWebHost without running Main. So Iconfiguration is null.

    Create a new class which inherited from IDesignTimeDbContextFactory.

    public class YourDbContext : DbContext
    {
    //Dbcontext implementation
    }
    
    public class YourDbContextFactory : IDesignTimeDbContextFactory<YourDbContext>
    {
        public YourDbContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<YourDbContext>();
            optionsBuilder.UseSqlServer("your connection string");
    
            return new YourDbContext(optionsBuilder.Options);
        }
    }
    

    You are using a new .net core EF which uses IHostBuilder.(in an older version like yours the provider is IWebHostBuilder).

    The tools first try to obtain the service provider by invoking the Program.CreateHostBuilder(), calling Build(), then accessing the Services property.

    You can learn more about Design-time DbContext Creation from Here

    It may happen from a condition in your startup file or while you are injecting. for example, you have a flag that checks if some variable in appsettings is true to use inmemory database instance.

    EF needs to build the model and use the DbContext without starting the application. When EF invokes methods, your config services are still null that's why you get an error.

    Make sure you have installed the package

    Microsoft.EntityFrameworkCore.Tools