C# ASP.NET核心:需要显式访问ServiceCollection吗?
我了解如何为ASP.NET core注册依赖项,以及构造函数注入如何为我的控制器工作(我有这个功能)。是否所有内容都必须通过构造函数传递,然后显式传递到由这些构造对象创建的对象,或者实例化的对象(例如我的控制器)及其创建的对象如何使用服务集合访问或实例化其他对象 更新日期:2020年6月19日: 假设我的初创公司调用了这个(这只是示例代码,看看我是否可以得到这个问题,从而取消我的帐户):C# ASP.NET核心:需要显式访问ServiceCollection吗?,c#,.net,.net-core,C#,.net,.net Core,我了解如何为ASP.NET core注册依赖项,以及构造函数注入如何为我的控制器工作(我有这个功能)。是否所有内容都必须通过构造函数传递,然后显式传递到由这些构造对象创建的对象,或者实例化的对象(例如我的控制器)及其创建的对象如何使用服务集合访问或实例化其他对象 更新日期:2020年6月19日: 假设我的初创公司调用了这个(这只是示例代码,看看我是否可以得到这个问题,从而取消我的帐户): 公共静态IServiceCollection AddRepository( 这是电子收款服务, i配置(配置
公共静态IServiceCollection AddRepository(
这是电子收款服务,
i配置(配置)
{
var serviceProvider=services.BuildServiceProvider();//TODO:dispose
ContentstackClient stack=serviceProvider.GetService();
Assert(stack!=null,“在IRepository服务之前配置ContentstackClient服务”);
IConfigureSerialization configurator=serviceProvider.GetService();
Assert(configurator!=null,“在ContentstackRepository之前配置IConfigureSerialization”);
configurator.ConfigureSerialization(堆栈序列化设置);
//TODO:从appsettings.json应用ContentstackRepositoryConfiguration(UseSync等)
ContentstackRepositoryConfiguration repoConfig=ContentstackRepositoryConfiguration.Get(
ContentstackRepositoryConfiguration.StartType.FastTestStartSync,堆栈);
services.AddSingleton(新ContentstackRepository(repoConfig));/,serviceProvider.GetService());
//TODO:自动发生?serviceProvider.Dispose();
返回服务;
}
我的控制器中有:
public EntryController(
IRepository repository,
ILogger<EntryController> logger,
ContentstackClient stack)
{
_repository = repository;
_logger = logger;
_stack = stack;
}
公共入口控制器(
i存储库,
ILogger记录器,
ContentstackClient(客户端堆栈)
{
_存储库=存储库;
_记录器=记录器;
_堆栈=堆栈;
}
但如果我或其他地方的代码想要访问IRepository单例呢?我是否必须将IRepository到处传递,或者是否有某种方式可以通过服务定位器或其他方式显式访问它?我认为您有两种选择:
我知道asp.net核心di支持三组件注入。
(1) 构造函数
(2)
(3) HttpContext.RequestServices
注意:HttpContext.RequestServices是一种服务定位器模式。这不是一个好的模式,但是如果您在某些情况下丢失了服务,并且在这种情况下可以获得HttpContext.RequestServices,那么您可以使用它。
下面是一个关于HttpContext.RequestServices的示例 我将重构您的代码以注册存储库,并提示一些提示将对您有所帮助
public static IServiceCollection AddRepository(
this IServiceCollection services,
IConfiguration configuration)
{
// You can declare 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);
});
}
公共静态IServiceCollection AddRepository(
这是电子收款服务,
i配置(配置)
{
//您可以声明Singleton实例,然后声明IRepository是服务,ContentstackRepository是您的实现类
//当您在控制器构造函数中使用pass-IRepository时,实际上您得到了ContentstackRepository实例。
services.AddSingleton(f=>
{
//如果要注册实例,请不要在IServiceCollection中使用此方法。
//var serviceProvider=services.BuildServiceProvider();
//您可以使用“f”lamda获取IServiceProvider,并使用GetService获取实例。
ContentstackClient stack=f.GetService();
Assert(stack!=null,“在IRepository服务之前配置ContentstackClient服务”);
IConfigureSerialization configurator=f.GetService();
Assert(configurator!=null,“在ContentstackRepository之前配置IConfigureSerialization”);
configurator.ConfigureSerialization(堆栈序列化设置);
//返回ContentstackRepository实例
ContentstackRepositoryConfiguration repoConfig=ContentstackRepositoryConfiguration.Get(ContentstackRepositoryConfiguration.StartType.FastestStartSync,stack);
返回新的ContentstackRepository(repoConfig);
});
}
如果要在其他类中使用IRepository单例,则需要在其他构造函数中传递IRepository。如果您想使用方法注入和属性注入,我认为您可以考虑这是有用的DI注入库。
< p>您至少有四个选项可以使用.NET内核中的依赖性注入: 构造函数注入:这是框架中的一些魔法。我不知道它是如何工作的,但至少当您没有显式地实例化对象时,它是如何工作的。控制器就是一个很好的例子。您所需要做的就是在控制器中实现构造函数,以接受框架从服务提供者实例化的参数。您可以将它们存储在控制器对象中,然后将它们传递给调用堆栈中更深的任何对象。确保在框架实例化控制器之前注册了所有必需的服务 第三方依赖注入框架:有很多具有各种特性和性能配置文件的框架,对我来说,所有这些框架都超出了范围,因为它们不是框架本身固有的,我不想把我的观点强加给任何使用我的代码的人。提到任何,我几乎肯定会排除一些,因为我不打算使用它们,所以我不会列出任何。其中哪一个能在即将到来的DI战争中幸存下来?谁知道呢。我想使用.NET本身,而不是第三方扩展 反射:您可以使用反射来检查一个或多个程序集中的类型,以查找满足约定或定义了属性的类型。我认为这是隐含的一种形式。services.AddSingleton<IRepository, [class_that_implements_IRepository]>();
public interface IRepository
{
int DoSomething();
}
public class MyRepositoryImplementation : IRepository
{
public int DoSomething()
{
return 42;
}
}
public static class MyRepositorySingleton
{
private static IRepository _repository = null;
static MyRepositorySingleton()
{
_repository = new MyRepositoryImplementation();
}
public static IRepository GetRepository()
{
return _repository;
}
}
public static IServiceCollection AddRepository(
this IServiceCollection services,
IConfiguration configuration)
{
// You can declare 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);
});
}