Dependencyinjection: Necesito apoyo Lazy<t/>

Creado en 19 ago. 2014  ·  3Comentarios  ·  Fuente: aspnet/DependencyInjection

DI debería ser compatible con Lazy.
No queremos crear una instancia de inmediato en algún momento.

Comentario más útil

Es posible agregar algunos métodos de extensión sobre IServiceCollection para agregar soporte Lazy con muy poco esfuerzo, sin requerir que todos los contenedores de IoC admitan esta función. ¿Pensamientos?

namespace Microsoft.Extensions.DependencyInjection
{
    using System;

    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> to the
        /// specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service to add.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService>(this IServiceCollection services)
            where TService : class
        {
            return services
                .AddScoped<TService>()
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> with a
        /// factory specified in <paramref name="implementationFactory"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory)
            where TService : class
        {
            return services
                .AddScoped(implementationFactory)
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> with an
        /// implementation type specified in <typeparamref name="TImplementation"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddScoped<TService, TImplementation>()
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> with an
        /// implementation type specified in <typeparamref name="TImplementation"/> using the factory specified in
        /// <paramref name="implementationFactory"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddScoped<TService, TImplementation>()
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> to the
        /// specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService>(this IServiceCollection services)
            where TService : class
        {
            return services
                .AddSingleton<TService>()
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with a
        /// factory specified in <paramref name="implementationFactory"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory)
            where TService : class
        {
            return services
                .AddSingleton(implementationFactory)
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with
        /// an instance specified in implementationInstance to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationInstance">The implementation instance.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService>(
            this IServiceCollection services,
            TService implementationInstance)
            where TService : class
        {
            return services
                .AddSingleton<TService>()
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with
        /// an implementation type specified in <typeparamref name="TImplementation"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddSingleton<TService, TImplementation>()
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with an implementation
        /// type specified in <typeparamref name="TImplementation"/> using the factory specified in <paramref name="implementationFactory"/>
        /// to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddSingleton<TService, TImplementation>(implementationFactory)
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService>(this IServiceCollection services)
            where TService : class
        {
            return services
                .AddTransient<TService>()
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> with a factory specified
        /// in <paramref name="implementationFactory"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory)
            where TService : class
        {
            return services
                .AddTransient(implementationFactory)
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> with an implementation
        /// type specified in <typeparamref name="TImplementation"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddTransient<TService, TImplementation>()
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> with an implementation
        /// type specified in <typeparamref name="TImplementation"/> using the factory specified in <paramref name="implementationFactory"/>
        /// to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddTransient(implementationFactory)
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }
    }
}

Todos 3 comentarios

Me gusta esta idea, pero no todos los contenedores de IoC en los que queremos que se ejecute ASP.NET lo admiten. Por ejemplo, parece que esta función está implementada como una extensión de Ninject .

Si desea utilizar Lazy<T> en su aplicación, puede optar por utilizar un contenedor de IoC con todas las funciones como Autofac o Ninject (con la extensión).

Es posible agregar algunos métodos de extensión sobre IServiceCollection para agregar soporte Lazy con muy poco esfuerzo, sin requerir que todos los contenedores de IoC admitan esta función. ¿Pensamientos?

namespace Microsoft.Extensions.DependencyInjection
{
    using System;

    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> to the
        /// specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service to add.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService>(this IServiceCollection services)
            where TService : class
        {
            return services
                .AddScoped<TService>()
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> with a
        /// factory specified in <paramref name="implementationFactory"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory)
            where TService : class
        {
            return services
                .AddScoped(implementationFactory)
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> with an
        /// implementation type specified in <typeparamref name="TImplementation"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddScoped<TService, TImplementation>()
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized scoped service of the type specified in <typeparamref name="TService"/> with an
        /// implementation type specified in <typeparamref name="TImplementation"/> using the factory specified in
        /// <paramref name="implementationFactory"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddScopedLazy<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddScoped<TService, TImplementation>()
                .AddScoped(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> to the
        /// specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService>(this IServiceCollection services)
            where TService : class
        {
            return services
                .AddSingleton<TService>()
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with a
        /// factory specified in <paramref name="implementationFactory"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory)
            where TService : class
        {
            return services
                .AddSingleton(implementationFactory)
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with
        /// an instance specified in implementationInstance to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationInstance">The implementation instance.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService>(
            this IServiceCollection services,
            TService implementationInstance)
            where TService : class
        {
            return services
                .AddSingleton<TService>()
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with
        /// an implementation type specified in <typeparamref name="TImplementation"/> to the specified
        /// <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddSingleton<TService, TImplementation>()
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized singleton service of the type specified in <typeparamref name="TService"/> with an implementation
        /// type specified in <typeparamref name="TImplementation"/> using the factory specified in <paramref name="implementationFactory"/>
        /// to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddSingletonLazy<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddSingleton<TService, TImplementation>(implementationFactory)
                .AddSingleton(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService>(this IServiceCollection services)
            where TService : class
        {
            return services
                .AddTransient<TService>()
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> with a factory specified
        /// in <paramref name="implementationFactory"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService>(
            this IServiceCollection services,
            Func<IServiceProvider, TService> implementationFactory)
            where TService : class
        {
            return services
                .AddTransient(implementationFactory)
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> with an implementation
        /// type specified in <typeparamref name="TImplementation"/> to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddTransient<TService, TImplementation>()
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }

        /// <summary>
        /// Adds a lazily initialized transient service of the type specified in <typeparamref name="TService"/> with an implementation
        /// type specified in <typeparamref name="TImplementation"/> using the factory specified in <paramref name="implementationFactory"/>
        /// to the specified <see cref="IServiceCollection"/>.
        /// </summary>
        /// <typeparam name="TService">The type of the service.</typeparam>
        /// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
        /// <param name="implementationFactory">The factory that creates the service.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddTransientLazy<TService, TImplementation>(
            this IServiceCollection services,
            Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService
        {
            return services
                .AddTransient(implementationFactory)
                .AddTransient(x => new Lazy<TService>(() => x.GetRequiredService<TService>()));
        }
    }
}

@RehanSaeed estas extensiones no funcionan cuando se intenta registrar múltiples implementaciones de la misma interfaz y usar GetServices

¿Fue útil esta página
0 / 5 - 0 calificaciones