- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们可以访问 IServiceProvider
作为:
public class ProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IServiceProvider serviceProvider)
{
_productRepository = serviceProvider.GetRequiredService<IProductRepository>();
}
...
}
所以很明显.net注册了IServiceProvider
默认情况下作为服务,但我检查了源代码:https://github.com/aspnet/Hosting/blob/master/src/Microsoft.Extensions.Hosting/HostBuilder.cs#L198
private void CreateServiceProvider() {
var services = new ServiceCollection();
services.AddSingleton(_hostingEnvironment);
services.AddSingleton(_hostBuilderContext);
services.AddSingleton(_appConfiguration);
services.AddSingleton<IApplicationLifetime, ApplicationLifetime>();
services.AddSingleton<IHostLifetime, ConsoleLifetime>();
services.AddSingleton<IHost, Host>();
services.AddOptions();
services.AddLogging();
foreach (var configureServicesAction in _configureServicesActions) {
configureServicesAction(_hostBuilderContext, services);
}
var containerBuilder = _serviceProviderFactory.CreateBuilder(services);
foreach (var containerAction in _configureContainerActions) {
containerAction.ConfigureContainer(_hostBuilderContext, containerBuilder);
}
_appServices = _serviceProviderFactory.CreateServiceProvider(containerBuilder); // _appServices is IServiceProvider
if (_appServices == null) {
throw new InvalidOperationException($"The IServiceProviderFactory returned a null IServiceProvider.");
}
}
所以我们可以看到,例如:
services.AddSingleton(_appConfiguration);
注册IConfiguration
(引擎盖下的 ConfigurationRoot
实例),这就是我们可以在 startup.cs 中使用它的原因:
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration { get; }
但是我看不到源码寄存器_appServices
( IServiceProvider
) 任何地方,都没有像 services.AddSingleton(_appServices);
这样的东西在源代码中
那么我们如何仍然可以访问 IServiceProvider
自动地?或者我一定是遗漏了什么地方,源代码确实注册了 IServiceProvider
其他地方?
最佳答案
当 BuildServiceProvider
扩展最终在服务集合上被调用时
/// <summary>
/// Creates a <see cref="ServiceProvider"/> containing services from the provided <see cref="IServiceCollection"/>
/// optionally enabling scope validation.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> containing service descriptors.</param>
/// <param name="options">
/// Configures various service provider behaviors.
/// </param>
/// <returns>The <see cref="ServiceProvider"/>.</returns>
public static ServiceProvider BuildServiceProvider(this IServiceCollection services, ServiceProviderOptions options)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return new ServiceProvider(services, options);
}
ServiceProvider
实例,将自身添加为服务。
internal ServiceProvider(ICollection<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)
{
// note that Root needs to be set before calling GetEngine(), because the engine may need to access Root
Root = new ServiceProviderEngineScope(this, isRootScope: true);
_engine = GetEngine();
_createServiceAccessor = CreateServiceAccessor;
_realizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
CallSiteFactory = new CallSiteFactory(serviceDescriptors);
// The list of built in services that aren't part of the list of service descriptors
// keep this in sync with CallSiteFactory.IsService
CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
CallSiteFactory.Add(typeof(IServiceScopeFactory), new ConstantCallSite(typeof(IServiceScopeFactory), Root));
CallSiteFactory.Add(typeof(IServiceProviderIsService), new ConstantCallSite(typeof(IServiceProviderIsService), CallSiteFactory));
if (options.ValidateScopes)
{
_callSiteValidator = new CallSiteValidator();
}
if (options.ValidateOnBuild)
{
List<Exception> exceptions = null;
foreach (ServiceDescriptor serviceDescriptor in serviceDescriptors)
{
try
{
ValidateService(serviceDescriptor);
}
catch (Exception e)
{
exceptions = exceptions ?? new List<Exception>();
exceptions.Add(e);
}
}
if (exceptions != null)
{
throw new AggregateException("Some services are not able to be constructed", exceptions.ToArray());
}
}
DependencyInjectionEventSource.Log.ServiceProviderBuilt(this);
}
关于c# - 默认情况下 IServiceProvider 是如何注入(inject)的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70529505/
我很难理解为什么在使用 IApplicationBuilder.ApplicationServices 时,在启动配置方法中应用服务定位器模式的行为会有所不同。而不是IServiceProvider
我正在使用 .Net Core,目前我正在使用它的 DI 引擎。 我的项目是一个类库,因此,asp的绑定(bind)在这里无关紧要。 我遵循了 this article 中的提示为了使 DI 工作。
TLDR:是否可以在 Startup 运行后修改 IServiceProvider? 我在运行时运行 dll(它实现了我的接口(interface))。因此有一个文件监听器后台作业,它会等到 plug
我是在探索 XNA 框架时提出这个问题的,但我希望有一个大致的了解。 ISomeService someService = (ISomeService)Game.GetServices(typeof(
IServiceProvider 基本上只是任何 IOC 容器的通用接口(interface),还是用于特定框架?我正在滚动我自己的轻量级 IOC 容器,我想知道我是否应该实现它。还有其他我应该实现的
我试图调试应用程序中的内存泄漏(请参阅相关的 question ),并且遇到了错误的行为。 在此代码中(当然是简化的代码片段): while (true) { usin
我正在尝试为 IServiceProvider 创建一个 Mock(使用 Moq),以便我可以测试我的存储库类: public class ApiResourceRepository : IApiRe
我正在使用 IHostBuilder在 .NET Core 2.1 控制台应用程序中。主要看起来像这样: public static async Task Main(string[] args
我正在编写一些设计时代码。我想使用这个片段:(找到 here) var dte = (EnvDTE.DTE) GetService(typeof(EnvDTE.DTE)); if (dte != nu
我想知道为什么不显式使用 IServiceProvider 来解决依赖关系,而不是单独注入(inject)每个依赖关系。换句话说,为什么要使用这种方法: public class A { pr
我需要在开源MFC应用程序中实现IServiceProvider接口(interface);特别是我的 TTSApp申请。 我正在尝试添加对 IAccessibleApplication interf
这是关于 .NET 的一般性问题 我得到了一个 IServiceProvider 的实例接口(interface),但我几乎没有关于从中可以得到什么的文档。我如何找到它可能提供的所有服务的列表? 最佳
我在查看我的一些旧代码时发现了一个混合的 IValueConverter/MarkupExtension 类。这让我想知道 ProvideValue 方法中的 IServiceProvider 是否真
我希望能够访问内置的 IoC 容器(IServiceProvider 我相信)。 我知道在代码中访问它通常是不好的做法,我们应该允许框架将所需的任何依赖项注入(inject)到 Controller
我需要使用 IServiceProvider 在 ASP.NET Core 1.0 的 ConfigureService 方法中访问 session 变量。 我有一个使用委托(delegate)/la
我正在研究 xamarin 表单上的“依赖注入(inject)”,并发现了一些使用类似 ContainerBuilder 的概念。 .网上找到的解决方案如this ,讨论如何进行 DI 设置并将它们注
我们可以访问 IServiceProvider作为: public class ProductService { private readonly IProductRepository _pr
我们可以访问 IServiceProvider作为: public class ProductService { private readonly IProductRepository _pr
如果您编写自己的 MarkupExtension,您可能会偶然发现 IServiceProvider serviceProvider 参数在设计时与运行时不同。例如,您无法获取 IRootObject
我正在实现一个新的 .NET Core 项目并为我的服务层进行依赖注入(inject)。我创建了一个实现 IServiceProvider 的接口(interface),现在必须实现 GetServi
我是一名优秀的程序员,十分优秀!