我正在使用具有以下类型的第三方库:
public interface IEngine
{
ICarburettor Carburettor { get; }
void VroomVroom();
}
internal class FooEngine : IEngine
{
public FooEngine(
ILogger<MerlinEngine> logger,
ICarburettor carburettor,
IDistributor distributor,
IExhaustManifold exhaustManifold
)
{
// ...
}
public ICarburettor Carburettor => this.carburettor;
void VroomVroom()
{
// ...
}
}
使用第三方库中的单个扩展方法IEngine
,将FooEngine
服务(具有AddFooEngine()
实现)添加到ASP.NET Core的服务集合中,该扩展方法还配置了所有其他依赖项(例如ICarburettor
等)。该AddFooEngine()
具有副作用,因此非常不希望使用私有IServiceBuilder
来称呼自己。
通常,我的应用程序将IEngine
作为普通的注入服务使用,它使用库自身的ICarburettor
实现,但是我需要将FooEngine
与单个特定的ICarburettor
一起使用只需一个请求即可实现。
我还注意到FooEngine
的构造函数还具有已注册的依赖关系-但是它们的接口和实现都是internal
,这增加了更多的难度。
所以理想情况下,我想做这样的事情:
public async Task<IActionResult> AControllerAction()
{
IServiceCollection services = GetExistingSetOfConfiguredServices();
services.Replace<ICarburettor,MyOwnCarburettor>();
ServiceProvider tempSP = services.BuildServiceProvider();
IEngine fooEngine = tempSP.GetRequiredService<IEngine>();
// Assert that `fooEngine` is still a FooEngine instance, but uses my own carburettor:
Debug.Assert( fooEngine.GetType().Name == "FooEngine" );
Debug.Assert( fooEngine.Carburettor.GetType().Name == "MyOwnCarburettor" );
fooEngine.VroomVroom();
}
但是,,,我不知道该怎么做GetExistingSetOfConfiguredServices()
。
我知道我可以通过使用ConstructorInfo
的缓存FooEngine
使用反射并在父类的注入依赖项中转发来解决此问题,但这是一个hack。
不幸的是,到目前为止,我在StackOverflow上看到的所有其他QA都与ConfigureServices
或Startup
内有关,而在覆盖服务时似乎并没有谈论单关的依赖关系解析单一类型的实现。