我在.NETStandard库中定义了一个接口,该库是HttpClient
个实例的工厂:
namespace Ofl.Net.Http
{
public interface IHttpClientFactory
{
Task<HttpClient> CreateAsync(HttpMessageHandler handler,
bool disposeHandler, CancellationToken cancellationToken);
}
}
.csproj文件中的<FrameworkTarget>
元素设置为netstandard1.1
(HttpClient
需要1.1)。
默认情况下引用.NETStandard.Library 1.6.1(尽管未在.csproj文件中明确指定)。
在同一个解决方案中,我从.NET Standard项目开始,将<FrameworkTargets>
元素设置为netcoreapp1.1;net461
。
我有一些测试来测试只是创建一个接口的实现(我通常不会测试它,但这会将它减少到最小的自包含可重现的示例)。
为了帮助解决这个问题,我有一个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);
}
基本上,通过具有接口实现类型的变量进行调用,并使用实现类的类型进行调用(尽管无关紧要)。
在.NETCoreApp 1.1框架中运行测试(通过Resharper或dotnet test
)时,所有测试都通过了。但是,在.NET Framework 4.6.1上运行时,我得到System.TypeLoadException
表示没有实现:
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上运行时测试没有通过?肯定是一种实施方式。
我认为可能是因为System.Net.Http
未在测试项目中引用(在接口定义中没有必要,因为引用了.NETStandard 1.6.1,引用了System.Net.Http
)所以我确定了添加它,但测试仍然在.NET Framework 4.6.1下失败。
完整的设置可以在这里找到:
信息
VS.NET 2017 .NET CLI:1.1.0 .NET桌面框架:4.61 .NET Core:1.1
答案 0 :(得分:7)
这是因为没有为您的程序集生成具有正确绑定重定向的.dll.config
文件,并且Test SDK不会自动设置所需的属性。
您可以将此添加到测试的.csproj
文件中来解决此问题:
<PropertyGroup Condition=" '$(TargetFramework)' == 'net461' ">
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
您将看到这会导致生成一个bin\Debug\net461\Ofl.Net.Http.Abstractions.Tests.dll.config
文件,其中包含System.Net.Http
的绑定重定向,并且您的测试应该正常运行。
即将推出的.net core / cli 2.0工具和测试sdk将包含一些应该修复此问题的更改,但这可能被认为是当前工具中的一个错误。