- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在使用 EF 6 设置 .NET Core 应用程序,但在理解如何正确使用各种依赖项注册方法时遇到了一些困难。据我了解:
特别是在我的情况下,我设置了一对 DbContext(基于 CQRS 模式)来处理我注册为 Scoped 的数据库查询/命令:
services.AddScoped((_) => new TestCommandContext(Configuration["Data:TestConnection:ConnectionString"]));
services.AddScoped((_) => new TestQueryContext(Configuration["Data:TestConnection:ConnectionString"]));
这是根据 ASP.NET Getting Started with ASP.NET 5 and Entity Framework 6 文档:
Context should be resolved once per scope to ensure performance and ensure reliable operation of Entity Framework
然后我将注册相应的 UOW 类(class):
services.AddTransient<ITestCommandUnit, TestCommandUnit>();
services.AddTransient<ITestQueryUnit, TestQueryUnit>();
我在这里使用 Transient 基于 this文章,这表明:
Services registered with Transient scope are created whenever it is needed within the application. That means a new instance of the (registered service) class will be created by the dependency injection framework every time the (method in which the dependency is created) is executed.
基于这种理解,我也在 Scoped 下注册我的存储库和服务类:
services.AddScoped<ITestCommandRepository, TestCommandRepository>();
services.AddScoped<ITestQueryRepository, TestQueryRepository>();
services.AddScoped<ITestCommandService, TestCommandService>();
services.AddScoped<ITestQueryService, TestQueryService>();
然后根据需要在我的 Controller 中调用我各自的服务层方法:
public class TestController : BaseController
{
private ITestQueryService testQueryService;
// Get new object of type TestQueryService via DI
public TestController(ITestQueryService testQueryService)
{
this.testQueryService = testQueryService;
}
[HttpGet]
public IActionResult Edit(int id)
{
if (id > 0)
{
EditViewModel viewModel = new EditViewModel();
viewModel.TestObject = testQueryService.GetById(id);
return View(viewModel);
}
else
{
return RedirectToAction("Error", new { errorMessage = "No object with the specified Id could be found." });
}
}
}
在测试中,此配置似乎有效,将 DbContext 设置为 Scoped 很有意义 - 每次请求时都创建一个新的上下文对象似乎没有必要/效率低下。
但是,对于其他对象,在Transient/Singleton/Scoped 之间的选择是我迷失的地方。有人可以帮助我了解这种特定模式实现的最佳配置吗?
上述设置正在运行,但我正在寻求更多地了解为什么我应该使用我所做的范围。 (即 Transient 是我的 UOW 类(class)的最佳选择吗?为什么在这种情况下它比 Singleton 更好?等等)
最佳答案
通常我的经验法则是:
Scoped - 是可行的方法,可以节省缓存和您的头发,因为状态是为整个请求共享的。没有并发问题(所有作用域服务共享一个线程)。如果类在单个请求中多次使用,则不会创建实例。如果我不知道应该如何注册类(class),我会选择 scoped。通常,您在单个请求中多次需要一些东西 - 您可以计算一次,并在字段中设置值,因此下一次对客户的 CreditLimit
的查询将不会访问数据存储。
单例适用于缓存(服务器范围)、配置类、设计时考虑了多线程(多个请求)的对象。请注意,单例不应依赖于作用域对象。还要注意在多个线程中调用单例。如果您需要单例对请求数据执行某些操作,请将其作为函数参数传递。
临时注册在我的应用程序中很少见。我将它用于具有内部状态的类,它们可以多次使用,并且不应共享该状态。通常是实用程序或框架类。
示例作用域类? SqlConnection - 您不想从单个请求打开到数据库的多个连接(因为它由连接池处理)。还使用该连接的服务(服务只做一件事,因此不需要多个实例)。 Asp Controller 。
示例单例?今天浏览最多的文章。邮政编码验证器(没有依赖关系,虽然可以是单例)。
transient 示例?想一想如果该请求中的所有列表共享状态会发生什么。列表不是服务请求,而是您的代码,并且可以在单个请求期间用于不同目的。
请记住,如果单例具有 transient 或作用域依赖性,它将不会被释放,直到单例被释放(应用程序回收)。因此,范围内的事物可以依赖于单例,但单例不能依赖于范围。
说到 CQRS 和 DbContext - 在我的应用程序中,我只有一个 DbContext,由命令和查询共享。一切都在每个生命周期范围内注册(命令或查询在完成后不会保留状态,因此可以重复使用。将其设置为 transient 也可以)。另一个例子是为 html 元素生成唯一 id 的类。它被注册为作用域,并在每次查询新 id 时递增内部计数器。如果类是 transient 的,当被下一个类调用时它会丢失它的状态。
请注意,有些人有其他观点。如果您使用多个生命周期范围,则最好转换为 transient 依赖项。如果我需要多次使用单个依赖项,我喜欢传递工厂,并且我尝试在我的应用程序中只有一个生命周期范围。
关于c# - .NET Core/EF 6 - 依赖注入(inject)范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37172161/
我已阅读有关依赖注入(inject)的信息。然后来了 构造函数注入(inject), setter/getter 注入(inject) 二传手注入(inject) 接口(interface)注入(in
我正在研究依赖注入(inject)模式。我看过很多例子,其中一个典型的例子是使用 XxxService/XxxRepository 作为例子。但是在我看来,按照UML的概念,类XxxRepositor
我开始使用 Google Guice。 我有一个简单的问题: javax.inject 的 @Inject 注释和 com.google.inject 的 有什么区别@Inject 一个 ? 谢谢。
当使用构造函数注入(inject)工厂方法时,依赖的属性不会得到解析。但是,如果在解析依赖的组件之前解析了工厂方法,则一切都会按预期工作。此外,当仅使用属性注入(inject)或构造函数注入(inje
我有这样的事情: class Root { public Root(IDependency dep) {} } class Dependency:IDependency { p
听完Clean Code Talks ,我开始明白我们应该使用工厂来组合对象。因此,例如,如果 House有一个 Door和 Door有一个 DoorKnob , 在 HouseFactory我们创建
情况:我需要在一些 FooClass 中进行惰性依赖实例化,所以我通过 Injector类作为构造函数参数。 private final Injector m_injector; public Foo
在编写代码时,我们应该能够识别两大类对象: 注入(inject)剂 新品 http://www.loosecouplings.com/2011/01/how-to-write-testable-cod
这个问题是关于 Unity Container 的,但我想它适用于任何依赖容器。 我有两个具有循环依赖关系的类: class FirstClass { [Dependency] pub
如果我有 10 个依赖项我需要注入(inject)并且不想在构造函数中有 10 个参数,我应该使用哪种注入(inject)模式? public class SomeClass { privat
我在使用 Angular2 DI 时遇到了问题。我尝试将一个类注入(inject)另一个类,它引发了以下错误: 留言:"Cannot resolve all parameters for 'Produ
对依赖注入(inject)还很陌生,我想弄清楚这是否是一种反模式。 假设我有 3 个程序集: Foo.Shared - this has all the interfaces Foo.Users -
我正在尝试了解 Angular 14 的变化,尤其是 inject()我可以将模块注入(inject)功能的功能,我不需要为此创建特殊服务..但我想我弄错了。 我正在尝试创建一些静态函数来使用包 ng
希望这个问题不是太愚蠢,我试图掌握更高级的编程原理,因此试图习惯使用 Ninject 进行依赖注入(inject)。 因此,我的模型分为几个不同的 .dll 项目。一个项目定义了模型规范(接口(int
我最近一直在大量使用依赖注入(inject)、测试驱动开发和单元测试,并且开始喜欢上它。 我在类中使用构造函数依赖,这样我就可以为单元测试注入(inject)模拟依赖。 但是,当您实际需要生产环境中的
我有下面的代码来使用 Guice 进行依赖注入(inject)。第一个是使用构造函数注入(inject),而另一个是直接在字段上方添加 @Inject。这两种方式有什么区别吗? Guice官网似乎推荐
这个问题在这里已经有了答案: Angular2 Beta dependency injection (3 个答案) 关闭 7 年前。 我正在使用 angular2 测试版。并在使用 @Inject
有没有可能做这样的事情? (因为我尝试过,但没有成功): @Injectable() class A { constructor(private http: Http){ // <-- Injec
我很恼火必须通过 Constructor 传递管道对象,因为我想为业务实体或要传递的值保留构造函数参数。 所以我想通过 setter ,但只要这些 setter 没有被填充,我的包含依赖项的对象就不应
假设我有这个: SomePage.razor: @inject Something something @page "/somepage" My Page @code { // Using
我是一名优秀的程序员,十分优秀!