testfx icon indicating copy to clipboard operation
testfx copied to clipboard

[MTP] Cannot inject IClientInfo into Capabilities

Open thomhurst opened this issue 7 months ago • 4 comments

I was trying to inject in the ClientInfo to the Banner capability, but it can't find it.

Guessing this is added to the service provider later?

Unhandled exception. System.InvalidOperationException: Cannot find service of type 'Microsoft.Testing.Platform.Services.IClientInfo'
   at Microsoft.Testing.Platform.Helpers.ApplicationStateGuard.Ensure(Boolean condition, String errorMessage) in /_/src/Platform/Microsoft.Testing.Platform/Helpers/ApplicationStateGuard.cs:line 16
   at Microsoft.Testing.Platform.Services.ServiceProviderExtensions.GetRequiredServiceInternal[TService](IServiceProvider provider) in /_/src/Platform/Microsoft.Testing.Platform/Services/ServiceProviderExtensions.cs:line 114
   at Microsoft.Testing.Platform.Services.ServiceProviderExtensions.GetClientInfo(IServiceProvider serviceProvider) in /_/src/Platform/Microsoft.Testing.Platform/Services/ServiceProviderExtensions.cs:line 105
   at TUnit.Engine.Capabilities.BannerCapability.GetBannerMessageAsync()

thomhurst avatar Jun 04 '25 19:06 thomhurst

Guessing this is added to the service provider later?

Correct. The banner is displayed during TestApplicationBuilder.BuildAsync while the IClientInfo is added during ITestApplication.RunAsync.

For console, IClientInfo is static and can be added very early, but for server and Json RPC, this is not the case. When running in server & json RPC, we only get to know the information when we handshake, which is later than when we want to display the banner.

Youssef1313 avatar Jun 04 '25 20:06 Youssef1313

@thomhurst Can I have more insights for the motivation to need this as part of the banner?

Youssef1313 avatar Jun 06 '25 06:06 Youssef1313

To be honest I probably don't. I was just thinking to print it to the user. But they'd only ever see it in console mode anyway so not like they'd ever see different client info.

However for other capabilities, wouldn't this be useful?

E.g.

class MySpecificFeatureCapability(ClientInfo client)
{
    bool IsSupported() => client.Name == "Visual Studio";
}

thomhurst avatar Jun 09 '25 17:06 thomhurst

It depends exactly on what kind of capability and "when" MySpecificFeatureCapability.IsSupported is getting called. Note that if the capability is created early, but IsSupported is called later, you can pass IServiceProvider to the capability constructor, then IsSupported can retrieve the client info.

Youssef1313 avatar Jun 09 '25 19:06 Youssef1313