我有一个ServiceCollection
,我想创建一个方法,我可以传入一组参数,并在请求匹配类型时让ServiceCollection
返回这些服务。我正在使用Autofixture创建我的服务。当我调用fixture.Create<IMyService>
时,它将返回一个Mock<IMyService>
。例如
public static IServiceProvider CreateServiceProvider(params object[] services)
{
var serviceCollection = new ServiceCollection();
foreach (object service in services)
{
serviceCollection.AddTransient(factory => service);
}
return serviceCollection.BuildServiceProvider();
}
然后我想这样用它
[Fact]
public void TestSomething()
{
// This causes myFirstService to be of type of type IMyFirstService,
// but have a value of type Mock<IMyFirstService> (same for
// mySecondService)
var fixture = new Fixture();
IMyFirstService myFirstService = fixture.Create<IMyFirstService>();
IMySecondService mySecondService = fixture.Create<IMySecondService>();
var serviceProvider = CreateServiceProvider(myFirstService, mySecondService);
// I want the returned objects to be myFirstService and mySecondService
// that I created above
var resolvedFirstService = serviceProvider.GetService<IMyFirstService>();
var resolvedSecondService = serviceProvider.GetService<IMySecondService>();
}
问题是myFirstService
和mySecondService
没有返回,因为当调用CreateServiceProvider
时,服务被转换为object
,所以它们在ServiceCollection
中注册为类型object
,而不是正确的接口类型。我尝试使用serviceProvider.GetService(service.GetType(), factory => service)
,但问题是service.GetType()
返回Castle.Proxies.IMyFirstServiceProxy
。
我知道我可以通过执行下面的代码来实现这一点,但我希望通过CreateServiceProvider
方法注册这些服务来实现这一点。
[Fact]
public void TestSomething()
{
var fixture = new Fixture();
IMyFirstService myFirstService = fixture.Create<IMyFirstService>();
IMySecondService mySecondService = fixture.Create<IMySecondService>();
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient(factory => myFirstService);
serviceCollection.AddTransient(factory => mySecondService);
var serviceProvider = serviceCollection.BuildServiceProvider();
var resolvedFirstService = serviceProvider.GetService<IMyFirstService>();
var resolvedSecondService = serviceProvider.GetService<IMySecondService>();
}
1条答案
按热度按时间vuktfyat1#
我不知道一个简单的方法来实现这一点,但如果你坚持这样做,你可以选择相当脆弱的反射路径,并扰乱实现细节:
但是这可能非常脆弱,所以我建议重新考虑这种方法,并使用
Type
作为参数:打电话像: