Как исправить «Метод ApplyServices не имеет реализации» в Программе с efCore 3 и .net core 3 - PullRequest
0 голосов
/ 15 октября 2019

Я разрабатываю новый веб-API на EfCore 3 и .net core 3 и не могу запустить его из-за ошибки «Метод ApplyServices» типа «Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal.SqlServerOptionsExtension» изСборка «Microsoft.EntityFrameworkCore.SqlServer, Version = 3.0.0.0» не имеет реализации.

Следует отметить, что ApplicationContext, который я добавляю в мой проект, находится в другом проекте (тоже .net core 3). Отладка показала, что в этой части кода происходит сбой приложения ->


    services
                    .AddDbContext<ApplicationContext>(options =>
                        options.UseSqlServer(connectionString));

Здесь вы можете увидеть все классы запуска


    public Startup(IConfiguration configuration)
            {
                _configuration = configuration;
            }

            private readonly IConfiguration _configuration;

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddOptions();

                var connectionString = _configuration.GetConnectionString("DefaultConnection");

                services
                    .AddDbContext<ApplicationContext>(options =>
                        options.UseSqlServer(connectionString));

                services.AddControllers()
                    .SetCompatibilityVersion(CompatibilityVersion.Latest)
                    .AddNewtonsoftJson(options =>
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

                services.AddHostedService<MigratorHostedService>();
            }

            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                app.UseCors("AllowAll");

                app.UseStaticFiles();

                app.UseRouting();
            } 

Вот MigratorHostedService


    private readonly IServiceProvider _serviceProvider;
            public MigratorHostedService(IServiceProvider serviceProvider)
            {
                _serviceProvider = serviceProvider;
            }

            public async Task StartAsync(CancellationToken cancellationToken)
            {
                using (var scope = _serviceProvider.CreateScope())
                {
                    var myDbContext = scope.ServiceProvider.GetRequiredService<ApplicationContext>();

                    await myDbContext.Database.MigrateAsync();
                }
            }

            public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; 

Вот программа

 private const int Port = ...;

        public static async Task Main()
        {
            var cts = new CancellationTokenSource();

            var host = Host.CreateDefaultBuilder();

            host.ConfigureWebHostDefaults(ConfigureWebHost);

            await host.Build()
                .RunAsync(cts.Token)
                .ConfigureAwait(false);
        }

        private static void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.UseUrls($"http://*:{Port}");
            builder.UseStartup<Startup>();
            builder.UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateOnBuild = true;
            });
        } 

Поскольку ядро ​​.net 3 является новым, я не нашел решения этой проблемы

Также пакеты моего проекта:


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

      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <NoWarn>$(NoWarn);NU1605</NoWarn>
      </PropertyGroup>

      <ItemGroup>
        <PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
        <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0-preview-18579-0056" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0-preview.19080.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0-preview.19080.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0-preview.19080.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.6" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.NETCore.DotNetAppHost" Version="3.0.0" />
        <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Utils" Version="3.0.0" />
        <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
      </ItemGroup>

    </Project>

ApplicationContext

public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
        {

        } 

1 Ответ

0 голосов
/ 15 октября 2019

Интерфейсы определяют сигнатуру функций - имя, аргументы, возвращаемое значение. Но они не могут определить какой-либо код для них. Они ожидают, что класс, который их реализует, даст им код. Вы должны дать реализацию.

Теперь это абсолютно правильная реализация для всех мыслимых функций интерфейса:

{
  throw new NotImplementedException();
}

Так же это:

{
  throw new NotSupportedException();
}

Это дажевыполняет правило «должны вернуть значение».

Это также реализация по умолчанию. И в некоторых случаях это может быть единственной реализацией. Не каждая функция каждого интерфейса может иметь разумную реализацию для каждого класса, который ее реализует. В некоторых случаях, если функция не реализована, даже ожидается .

Если вы управляете этим классом, вы должны предоставить для этой функции исполнительную реализацию.

Если выне контролируйте этот класс, тогда вам во многом не повезло.

Я не вижу ни одного звонка на ApplyServices. Это означает, что вы передаете экземпляр некоторому коду, который ожидает, что функция существует (и имеет разумное поведение). Что не так.

Что бы вы ни пытались сделать, ожидается, что класс с кодом для ApplyServices не может быть применен к этому классу. Должен быть способ передать код функции. Как будто есть переопределение для Array.Sort (), которое принимает пользовательский Comparer, вместо использования по умолчанию Comparer. Но если нет, то это просто запрет.

...