How to use Func in built-in dependency injection

前端 未结 6 800
梦毁少年i
梦毁少年i 2021-02-14 11:17

Using asp.net 5 I\'d like my controller to be injected with a Funcinstead of T

For example:



        
6条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-14 11:52

    There are a few options available to you, the first is you can switch over to use the incredible Lamar (with it's ASP.NET Core integration).

    For the most part, switching to Lamar is a few lines of code, and you'll be able to resolve Func<> and Lazy<> all day long.

    I've been using it at scale for a while on a large microservices based platform and we're completely happy with it *.

    If you don't want to move over to Lamar, you can use this for resolving Lazy<> (sorry, I've tried and tried, and I can't get it to work with Func<>:

    // Add to your Service Collection.
    services.AddTransient(typeof(Lazy<>), typeof(LazyServiceFactory<>));
    
    class LazyServiceFactory : Lazy
    {
        public LazyServiceFactory(IServiceProvider serviceProvider)
            : base(() => serviceProvider.GetRequiredService())
        {
        }
    }
    

    And just for completeness, here's a test too.

    // And some tests...
    [TestMethod]
    [DataTestMethod]
    [DataRow(ServiceLifetime.Transient)]
    [DataRow(ServiceLifetime.Scoped)]
    [DataRow(ServiceLifetime.Singleton)]
    public void Resolve_GivenLazyilyRegisteredService_CanResolve(ServiceLifetime serviceLifetime)
    {
        // Arrange
        IServiceProvider serviceProvider = CreateServiceProvider(serviceLifetime);
        using IServiceScope scope = serviceProvider.CreateScope();
    
        // Act
        Func> result = () => scope.ServiceProvider.GetRequiredService>();
    
        // Assert
        result
            .Should()
            .NotThrow()
            .And
            .Subject()
            .Value
            .Should()
            .NotBeNull();
    }
    
    static IServiceProvider CreateServiceProvider(ServiceLifetime serviceLifetime)
    {
        IServiceCollection services = new ServiceCollection();
    
        services.Add(new ServiceDescriptor(typeof(Lazy<>), typeof(LazyServiceFactory<>), serviceLifetime));
    
        services.Add(new ServiceDescriptor(typeof(ClassHello), typeof(ClassHello), serviceLifetime));
    
        return services.BuildServiceProvider(true);
    }
    
    

    I've not put this through it's paces as I use Lamar pretty much exclusivly now, but this has come in handy for smaller/ disposable projects.

    * My only minor issue is that it doesn't support IAsyncDisposable yet.

提交回复
热议问题