.NETStandard 1.1 库中的接口在 .NET 4.61 中没有实现 [英] Interface in .NETStandard 1.1 library does not have implementation in .NET 4.61

查看:24
本文介绍了.NETStandard 1.1 库中的接口在 .NET 4.61 中没有实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 .NETStandard 库中定义了一个接口,它是 HttpClient 实例的工厂:

I'm defining an interface in a .NETStandard library that is a factory for a HttpClient instances:

namespace Ofl.Net.Http
{
    public interface IHttpClientFactory
    {
        Task<HttpClient> CreateAsync(HttpMessageHandler handler, 
            bool disposeHandler, CancellationToken cancellationToken);
    }
}

.csproj 文件中的 元素设置为 netstandard1.1(HttpClient 需要 1.1).

The <FrameworkTarget> element in the .csproj file is set to netstandard1.1 (HttpClient requires 1.1).

.NETStandard.Library 1.6.1 默认被引用(虽然没有在 .csproj 文件中明确指定).

.NETStandard.Library 1.6.1 is referenced by default (although not explicitly specified in the .csproj file).

在同一个解决方案中,我从一个 .NET Standard 项目开始,并将 元素设置为 netcoreapp1.1;net461.

In the same solution, I start with a .NET Standard project and set the <FrameworkTargets> element to netcoreapp1.1;net461.

我有一些测试来测试只是创建接口的实现(我通常不会测试这个,但这将它减少到最小的自包含可复制示例).

I have some tests to test just creating an implementation of the interface (I wouldn't normally test this, but this reduces it to the smallest self contained reproducible example).

为此,我有一个 IHttpClientFactory 的私有实现:

To aid in this, I have a private implementation of IHttpClientFactory:

private class HttpClientFactory : IHttpClientFactory
{
    #region Implementation of IHttpClientFactory

    public Task<HttpClient> CreateAsync(HttpMessageHandler handler, 
        bool disposeHandler, CancellationToken cancellationToken)
    {
        // Return a new client.
        return Task.FromResult(new HttpClient());
    }

    #endregion
}

然后是测试:

[Fact]
public async Task Test_CreateAsync_Interface_Async()
{
    // Cancellation token.
    CancellationToken cancellationToken = CancellationToken.None;

    // The client factory.
    IHttpClientFactory factory = new HttpClientFactory();

    // Not null.
    Assert.NotNull(factory);

    // Create client.
    HttpClient client = await factory.CreateAsync(null, true,
        cancellationToken).ConfigureAwait(false);

    // Not null.
    Assert.NotNull(client);
}

[Fact]
public async Task Test_CreateAsync_Concrete_Async()
{
    // Cancellation token.
    CancellationToken cancellationToken = CancellationToken.None;

    // The client factory.
    var factory = new HttpClientFactory();

    // Not null.
    Assert.NotNull(factory);

    // Create client.
    HttpClient client = await factory.CreateAsync(null, true,
        cancellationToken).ConfigureAwait(false);

    // Not null.
    Assert.NotNull(client);
}

基本上,通过具有接口实现类型的变量和具有实现类类型的变量进行调用(尽管这无关紧要).

Basically, making a call through a variable with a type of the interface implementation, and a variable with a type of the implementing class (that doesn't matter though).

在 .NETCoreApp 1.1 框架中运行测试(通过 Resharper 或 dotnet test)时,所有测试均通过.但是,在 .NET Framework 4.6.1 上运行时,我收到一个 System.TypeLoadException 说明没有实现:

When running the tests (through Resharper, or dotnet test) in .NETCoreApp 1.1 framework has all tests passing. However, when running on the .NET Framework 4.6.1, I get a System.TypeLoadException stating that there is no implementation:

System.TypeLoadException : Method 'CreateAsync' in type 'HttpClientFactory' from assembly 'Ofl.Net.Http.Abstractions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at Ofl.Net.Http.Abstractions.Tests.HttpClientFactoryTests.<Test_CreateAsync_Interface_Async>d__1.MoveNext()
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at Ofl.Net.Http.Abstractions.Tests.HttpClientFactoryTests.Test_CreateAsync_Interface_Async()

为什么在 .NET Framework 4.6.1 上运行时测试没有通过?肯定有一个实现.

Why doesn't the test pass when running on the .NET Framework 4.6.1? There's most certainly an implementation.

我认为可能是因为 System.Net.Http 在测试项目中没有被引用(在接口定义中不是必需的,因为引用了 .NETStandard 1.6.1,它引用了 System.Net.Http) 所以我确保添加了它,但是在 .NET Framework 4.6.1 下测试仍然失败.

I thought it could be because System.Net.Http wasn't referenced in the test project (not necessary in the interface definition because .NETStandard 1.6.1 is referenced, which references System.Net.Http) so I made sure to add that, but the test still fails under the .NET Framework 4.6.1.

可以在此处找到完整设置:

The full setup can be found here:

https://github.com/OneFrameLink/Ofl.Net.http.Abstractions/tree/c2bc5499b86e29c2e0a91282ca7dabcc1acc1176

信息

VS.NET 2017.NET 命令行界面:1.1.0.NET 桌面框架:4.61.NET 核心:1.1

VS.NET 2017 .NET CLI: 1.1.0 .NET Desktop Framework: 4.61 .NET Core: 1.1

推荐答案

这是因为没有为您的程序集生成具有正确绑定重定向的 .dll.config 文件,而测试 SDK 没有生成设置所需的属性以自动执行此操作.

This is because no .dll.config file with the correct binding redirects is generated for your assembly and the Test SDK doesn't set the required properties to do this automatically.

您可以通过将其添加到测试的 .csproj 文件来解决此问题:

You can work around this by adding this to your test's .csproj file:

  <PropertyGroup Condition=" '$(TargetFramework)' == 'net461' ">
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
  </PropertyGroup>

您会看到这会导致生成一个 binDebug et461Ofl.Net.Http.Abstractions.Tests.dll.config 文件,其中包含 System 的绑定重定向.Net.Http 并且您的测试应该可以正常运行.

You'll see that this causes a binDebug et461Ofl.Net.Http.Abstractions.Tests.dll.config file to be generated that includes binding redirects for System.Net.Http and your tests should run properly.

即将推出的 .net core/cli 2.0 工具和测试 sdk 将包括一些应该解决此问题的更改,但这可能被视为当前工具中的错误.

The upcoming tooling for .net core / cli 2.0 and the test sdk will include a few changes that should fix this but this may be considered a bug in the current tooling.

这篇关于.NETStandard 1.1 库中的接口在 .NET 4.61 中没有实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆