Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 236
cickness Avatar asked Mar 06 '20 10:03

cickness


5 Answers

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

Create 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

like image 69
Shervin Ivari Avatar answered Nov 07 '22 11:11

Shervin Ivari


As the accepted answer suggested:

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

But instead of using a more complex factory, You can use this simple solution by overriding OnConfiguring.

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

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Chinook");
        }
    }

*Pay attention for not using the db connection string inside the source code (docs)

dotnet user-secrets set ConnectionStrings:Chinook "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook"
dotnet ef dbcontext scaffold Name=ConnectionStrings:Chinook Microsoft.EntityFrameworkCore.SqlServer

also pay attention to use only one \ in the cli command line.

like image 5
Shahar Shokrani Avatar answered Nov 07 '22 11:11

Shahar Shokrani


My experience with this particular error has everything to do with running in powershell and not setting the appropriate environment variable for ASPNETCORE_ENVIRONMENT.

$env:ASPNETCORE_ENVIRONMENT = "Development"

Then:

Add-Migration...
Update-Database...
etc...

like image 4
Aquaritek Avatar answered Nov 07 '22 10:11

Aquaritek


In my case, I removed the arguments between the parentheses:

before:

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

after:

services.AddDbContext<EmployeeContext>();

Following Docs

like image 1
Lucas Costa Avatar answered Nov 07 '22 10:11

Lucas Costa


I got the same error message, but it was due to a different type mistake, sharing with you all, it might be useful.

I injected the service incorrectly,

wrong injection : ---> services.AddIdentity<IdentityUser, IdentityUser>().AddEntityFrameworkStores<AppDbContext>();

correct way ---> services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AppDbContext>();

like image 1
Sarfaraz Ansari Avatar answered Nov 07 '22 09:11

Sarfaraz Ansari