Azure / Azure/azure-functions-host

Service resolution inconsistent when binding to generic interface with contravariant parameters

Open
#4,905 2 comments 0 reactions 0 assignees View on GitHub
area: dependency injection
Dominant language
C#
Stars
2k
Forks
482
Avg merge
2d 12h
Merged PRs (30d)
38

Description

When adding DI bindings for generic interfaces with contravarient parameters, service provider results called by `ServiceProviderServiceExtensions.GetServices` returns different values depending on whether calling in `Startup` after binding and building provider, or when called from an Azure function.

Consider the following:

```csharp
public class Base { }

public class Child : Base { }

public interface IGenericInterface { }

public class Implementation : IGenericInterface{ }

public class Startup(IFunctionsHostBuilder builder)
{
// register bindings
builder.Services.AddTransient(typeof(IGenericInterface), t => new Implementation());

var serviceProvider = builder.Services.BuildServiceProvider();

// get all for unregistered binding
// returns 0 results as expected
var implementations = serviceProvider.GetServices>();
}

public class MyFunction
{
public MyFunction(IServiceProvider serviceProvider)
{
// get all for unregeistered binding
// bug: returns an instance of Implementation, which doesn't actually implement the interface!
var implementations = serviceProvider.GetServices>();
}

// Triggers/Functions
// ...

}

```

This seems a bug; it's inconsistent as well as returning an instance that doesn't actually implement the requested type.

Packages used;
`Microsoft.Azure.Functions.Extensions (1.0.0)`
`Microsoft.NET.Sdk.Functions (1.0.29)`

Contributor guide

Open the contributing guide

Research direction

Start by tracing ServiceProviderServiceExtensions.GetServices from the Startup and MyFunction examples, then inspect the dependency-injection behavior used by the Azure Functions host. Reproduce the contravariant generic-interface case with the packages listed in the issue. Done means resolution is consistent in both contexts and does not return an instance that fails the requested interface type.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, csharp
Domain
backend, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.