gpt4 book ai didi

c# - ASP.NET 核心 : need to access ServiceCollection explicitly?

转载 作者:行者123 更新时间:2023-12-05 02:54:06 25 4
gpt4 key购买 nike

我了解如何为 ASP.NET Core 注册依赖项,以及构造函数注入(inject)如何为我的 Controller 工作(我有那个工作)。是否所有的东西都必须通过构造函数传递,然后显式地传递给那些构造对象创建的对象,或者实例化的对象(例如我的 Controller 及其创建的对象)如何使用服务集合来访问或实例化其他对象对象?

2020 年 6 月 19 日更新:

假设我的 Startup 调用这个(这只是示例代码,看看我是否可以得到这个问题,因此我的帐户被取消):

    public static IServiceCollection AddRepository(
this IServiceCollection services,
IConfiguration configuration)
{
var serviceProvider = services.BuildServiceProvider(); //TODO: dispose
ContentstackClient stack = serviceProvider.GetService<ContentstackClient>();
Trace.Assert(stack != null, "configure ContentstackClient service before IRepository service");
IConfigureSerialization configurator = serviceProvider.GetService<IConfigureSerialization>();
Trace.Assert(configurator != null, "configure IConfigureSerialization before ContentstackRepository");
configurator.ConfigureSerialization(stack.SerializerSettings);
//TODO: Apply ContentstackRepositoryConfiguration (UseSync, etc.) from appsettings.json
ContentstackRepositoryConfiguration repoConfig = ContentstackRepositoryConfiguration.Get(
ContentstackRepositoryConfiguration.StartType.FastestStartSync, stack);
services.AddSingleton<IRepository>(new ContentstackRepository(repoConfig));//, serviceProvider.GetService<ILogger>()));
//TODO: happens automatically? serviceProvider.Dispose();
return services;
}

我的 Controller 里有这个:

    public EntryController(
IRepository repository,
ILogger<EntryController> logger,
ContentstackClient stack)
{
_repository = repository;
_logger = logger;
_stack = stack;
}

但是,如果我认为或其他地方的代码想要访问 IRepository 单例怎么办?我是否必须到处传递 IRepository,或者是否有某种方式可以通过服务定位器或其他方式显式访问它?

最佳答案

我知道asp.net core DI框架支持三种类型的组件注入(inject)。
(一)构造器
(2) Paramter invocation
(3) HttpContext.RequestServices

注意:HttpContext.RequestServices 使用服务定位器模式。这不是一个好的模式,但如果您失去了对服务的访问权限并且只能通过 HttpContext.RequestServices 获取它,那么它可能是可以接受的。
这是一个discussion关于它。

我重构了您的代码以注册一个Repository 服务。

public static IServiceCollection AddRepository(
this IServiceCollection services,
IConfiguration configuration)
{
// You can declare a singeton instance then declare IRepository is service and ContentstackRepository is your implementation class
// When you use pass IRepository in the controller constructor, actually you get the ContentstackRepository instance.
services.AddSingleton<IRepository, ContentstackRepository>(f =>
{
// Don't use this approach in the IServiceCollection, if you want register the instance.
// var serviceProvider = services.BuildServiceProvider();

// You can use the 'f' lamda to get IServiceProvider and use GetService to get the instance.
ContentstackClient stack = f.GetService<ContentstackClient>();
Trace.Assert(stack != null, "configure ContentstackClient service before IRepository service");

IConfigureSerialization configurator = f.GetService<IConfigureSerialization>();
Trace.Assert(configurator != null, "configure IConfigureSerialization before ContentstackRepository");
configurator.ConfigureSerialization(stack.SerializerSettings);

// return ContentstackRepository instance
ContentstackRepositoryConfiguration repoConfig = ContentstackRepositoryConfiguration.Get(ContentstackRepositoryConfiguration.StartType.FastestStartSync, stack);
return new ContentstackRepository(repoConfig);
});
}

如果你想在另一个类中使用IRepository单例,你需要将它传递给构造函数。

如果想使用方法或者属性注入(inject),可以考虑使用Autofac这是很有用的 di 注入(inject)库。

关于c# - ASP.NET 核心 : need to access ServiceCollection explicitly?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61941315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com