question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[DI] Pass the requested type to the implementation factory to enable dynamic scenarios when the type isn't known statically

See original GitHub issue

Is your feature request related to a problem? Please describe.

I’m trying to enable lazy injection of services, i.e. if I registered a service for IFoo, I’d like to be able to inject a Lazy<IFoo> or Func<IFoo>. This is useful to solve circular dependency issues; Unity does this automatically. So I’d like to be able to do this:

services.AddTransient(typeof(Lazy<>), provider => 
{
    ...
});

However, in the factory delegate, I don’t have access to the requested type, so I can’t dynamically create a Lazy<T> of the appropriate type.

Describe the solution you’d like

Having overloads of Add* that accept a Func<IServiceProvider, Type, object> would solve this. However it looks like it would be non-trivial, since the Func<IServiceProvider, object> signature is used all the way down to the low-level implementation…

Alternatively, implementing lazy injection like in Unity would solve my immediate problem, but would be less extensible.

Describe alternatives you’ve considered

Using a third-party container like Unity. But I’d rather keep using the built-in DI container.

Additional context

N/A

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:4
  • Comments:17 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
dotnetchriscommented, Nov 20, 2018

@pakrym this is literally one of the most critical features of a container

0reactions
thomaslevesquecommented, Sep 5, 2019

Much needed feature. Please consider to implement it.

As much as I’d like it, I don’t think it will ever be implemented. The team’s position is quite clear: they don’t want to introduce a breaking change, and it’s already possible to do it by using a different container.

In the meantime, I have a solution for my initial problem (lazily resolved service):

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddLazyResolution(this IServiceCollection services)
    {
        return services.AddTransient(typeof(LazyService<>));
    }
}

public class LazyService<T>
{
    private readonly Lazy<T> _service;
    
    public LazyService(IServiceProvider serviceProvider)
    {
        _service = new Lazy<T>(() => serviceProvider.GetRequiredService<T>());
    }
    
    public T Value => _service.Value;
}

Usage:

public void ConfigureServices(IServiceCollection services)
{
    services.AddLazyResolution();
    services.AddSingleton<Foo>();
    services.AddSingleton<Bar>();
}

class Foo
{
    public Foo(Bar bar)
    {
        Bar = bar;
    }
    
    public Bar Bar { get; }
}

class Bar
{
    private readonly LazyService<Foo> _foo;
    
    public Bar(LazyService<Foo> foo)
    {
        _foo = foo;
    }
    
    public Foo Foo => _foo.Value;
}

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Using a Strategy and Factory Pattern with Dependency ...
My challenge comes about when a strategy (built from a factory) requires different parameters for each possible constructor and implementation.
Read more >
Dependency Injection with multiple, dynamically created ...
DI is a factory implementation that is invoked dynamically when object A is instantiated to resolve the instances of any dependent objects  ......
Read more >
Configuring dependency providers
The useFactory provider key lets you create a dependency object by calling a factory function. With this approach you can create a dynamic...
Read more >
New dependency injection features in .NET 6
In this post I talk about some of the new features added to the DI libraries in .NET 6, as well a performance...
Read more >
Factory Method Design Pattern - C#
The creation of object is done when it is required. The Factory method allows a class later instantiation to subclasses.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found