为什么每次都需要调用BuildServiceProvider来获取依赖呢?

2024-04-02

在我的上注册实例后IServiceCollection,我需要注册一个IAutomapperProvider这取决于IAssemblyProvider在此方法调用之前已注册。

public static IServiceCollection RegisterAutomapperConfiguration(this IServiceCollection container, ServiceLifetime lifeTime = ServiceLifetime.Scoped)
{
    // creating the provider to get the IAssemblyProvider for my IAutomapperProvider
    var prov = container.BuildServiceProvider();
    var assemblyProvider = prov.GetService<IAssemblyProvider>();
    container.Register<IAutomapperProvider>(aProv => new AutomapperProvider(assemblyProvider), lifeTime);
    var autoMapperProvider = prov.GetService<IAutomapperProvider>();
    var mapperConfig = autoMapperProvider.GetMapperConfiguration();
    ...
}

如果在拨打电话后立即container.Register<IAutomapperProvider>(aProv => new AutomapperProvider(assemblyProvider), lifeTime);我不再调用BuildServiceProvider,那么我就得不到我之前注册的IAutomapperProvider。

public static IServiceCollection RegisterAutomapperConfiguration(this IServiceCollection container, ServiceLifetime lifeTime = ServiceLifetime.Scoped)
{
    // creating the provider to get the IAssemblyProvider for my IAutomapperProvider
    var prov = container.BuildServiceProvider();
    var assemblyProvider = prov.GetService<IAssemblyProvider>();
    container.Register<IAutomapperProvider>(aProv => new AutomapperProvider(assemblyProvider), lifeTime);
    prov = container.BuildServiceProvider();
    var autoMapperProvider = prov.GetService<IAutomapperProvider>();
    var mapperConfig = autoMapperProvider.GetMapperConfiguration();
    ...
}

在 AspNetCore 代码上,当您调用 BuildServiceProvider 扩展方法时,它们使用相同的 IServiceCollection,该 IServiceCollection 可以随着时间的推移而更改,添加更多元素,最后您指向相同的引用。

public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
{
    return BuildServiceProvider(services, ServiceProviderOptions.Default);
}

那么为什么我需要再次调用它来获取一个知道如何解析我的服务的新实例呢?

为了避免混淆,Register 方法是我创建的扩展,但在内部它调用 AddSingleton 或 Add...

public static IServiceCollection Register<TService>(this IServiceCollection container, Func<IServiceProvider, TService> implementationFactory, ServiceLifetime lifeTime)
            where TService : class
{
    if (container == null)
        throw new ArgumentNullException(nameof(container));
    if (implementationFactory == null)
        throw new ArgumentNullException(nameof(implementationFactory));

    switch (lifeTime)
    {
        case ServiceLifetime.Scoped:
            container.AddScoped(typeof(TService), (Func<IServiceProvider, object>)implementationFactory);
            break;
        case ServiceLifetime.Transient:
            container.AddTransient(typeof(TService), (Func<IServiceProvider, object>)implementationFactory);
            break;
        default:// ServiceLifetime.Singleton
            container.AddSingleton(typeof(TService), (Func<IServiceProvider, object>)implementationFactory);
            break;
    }
    return container;
}

BuildServiceProvider不必如此频繁地调用。

这就是实现工厂代表的用途。为此目的,他们提供对服务提供商的访问。

仍然不确定为什么您必须在第一个实例中构建提供程序,但根据当前提供的代码,在注册提供程序时使用实现工厂委托中的服务提供程序。

public static IServiceCollection RegisterAutomapperConfiguration(this IServiceCollection services, 
    ServiceLifetime lifeTime = ServiceLifetime.Scoped) {

    services.Register<IAutomapperProvider>(p => //<-- p is IServiceProvider
         //use the provider to get the IAssemblyProvider for my IAutomapperProvider
        new AutomapperProvider(p.GetService<IAssemblyProvider>()), lifeTime);
    prov = services.BuildServiceProvider();
    var autoMapperProvider = prov.GetService<IAutomapperProvider>();
    var mapperConfig = autoMapperProvider.GetMapperConfiguration();
    //...
}

When BuildServiceProvider被调用时,创建的服务提供者将只知道构建集合时集合中的类型。它不会知道任何其他类型,这就是为什么它通常在注册所有类型结束时完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么每次都需要调用BuildServiceProvider来获取依赖呢? 的相关文章

随机推荐