我了解如何为 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/