我想在ASP.NET Core中实现依赖注入(DI)。因此,在将此代码添加到ConfigureServices方法后,这两种方法都可以工作。

ASP.NET Core中的services.AddTransient和service.AddScoped方法之间有什么区别?

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddScoped<IEmailSender, AuthMessageSender>();
}

当前回答

在.NET的依赖注入中,有三个主要的生命周期:

在整个应用程序中创建单个实例的Singleton。它第一次创建实例,并在所有调用中重用相同的对象。

作用域内的每个请求创建一次作用域生存期服务。它相当于当前范围中的单例。例如,在MVC中,它为每个HTTP请求创建一个实例,但在同一web请求中的其他调用中使用相同的实例。

每次请求时都会创建短暂的生命周期服务。这种生命周期最适合于轻量级、无状态服务。

在这里,您可以找到和示例来了解不同之处:

ASP.NET 5 MVC6依赖注入,分6个步骤进行(由于链接无效,导致web存档链接)

依赖项注入就绪的ASP.NET:ASP.NET 5

这是官方文件的链接:

ASP.NET核心中的依赖注入

其他回答

这张图片很好地说明了这个概念。不幸的是,我找不到这个图像的来源,但有人制作了它,他以图像的形式很好地展示了这个概念。

更新:图片参考:ASP.NET核心服务生命周期(Infographic),作者:@WaqasAnwar

添加单体()

AddSingleton()在首次请求时创建服务的单个实例,并在需要该服务的所有地方重用该实例。

添加作用域()

在作用域服务中,对于每个HTTP请求,我们都会得到一个新实例。然而,在同一HTTP请求中,如果在多个位置(如视图和控制器中)需要服务,则为该HTTP请求的整个范围提供相同的实例。但是,每个新的HTTP请求都将获得服务的新实例。

添加过渡()

对于瞬时服务,无论服务实例是在同一HTTP请求的范围内还是跨不同HTTP请求,每次请求服务实例时都会提供一个新实例。

Singleton是应用程序生命周期中的单个实例领域作用域是作用域期间的单个实例请求,这意味着ASP.NET中的每个HTTP请求。瞬态是每个代码请求的单个实例。

通常,代码请求应该通过构造函数参数进行,如

public MyConsumingClass(IDependency dependency)

我想在@akazemis的回答中指出,DI上下文中的“服务”并不意味着RESTful服务;服务是提供功能的依赖项的实现。

在寻找这个问题的答案后,我找到了一个很好的解释,并列举了一个我想与大家分享的例子。

您可以在此处观看演示差异的视频

在此示例中,我们有以下给定代码:

public interface IEmployeeRepository
{
    IEnumerable<Employee> GetAllEmployees();
    Employee Add(Employee employee);
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class MockEmployeeRepository : IEmployeeRepository
{
    private List<Employee> _employeeList;

    public MockEmployeeRepository()
    {
        _employeeList = new List<Employee>()
    {
        new Employee() { Id = 1, Name = "Mary" },
        new Employee() { Id = 2, Name = "John" },
        new Employee() { Id = 3, Name = "Sam" },
    };
    }

    public Employee Add(Employee employee)
    {
        employee.Id = _employeeList.Max(e => e.Id) + 1;
        _employeeList.Add(employee);
        return employee;
    }

    public IEnumerable<Employee> GetAllEmployees()
    {
        return _employeeList;
    }
}

家庭控制器

public class HomeController : Controller
{
    private IEmployeeRepository _employeeRepository;

    public HomeController(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    }

    [HttpGet]
    public ViewResult Create()
    {
        return View();
    }

    [HttpPost]
    public IActionResult Create(Employee employee)
    {
        if (ModelState.IsValid)
        {
            Employee newEmployee = _employeeRepository.Add(employee);
        }

        return View();
    }
}

创建视图

@model Employee
@inject IEmployeeRepository empRepository

<form asp-controller="home" asp-action="create" method="post">
    <div>
        <label asp-for="Name"></label>
        <div>
            <input asp-for="Name">
        </div>
    </div>

    <div>
        <button type="submit">Create</button>
    </div>

    <div>
        Total Employees Count = @empRepository.GetAllEmployees().Count().ToString()
    </div>
</form>

启动.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddSingleton<IEmployeeRepository, MockEmployeeRepository>();
}

复制粘贴此代码,然后按视图中的创建按钮,然后在AddSingleton、AddScoped和AddTransient每次都会得到不同的结果,这可能会帮助您理解这一点。

AddSingleton()-顾名思义,AddSingletton()方法创建单人服务。Singleton服务在首次创建时创建请求。然后,所有后续的请求。所以一般来说,Singleton服务只创建一次每个应用程序,并且在整个应用寿命。AddTransient()-此方法创建一个Transient服务。一个新的每次请求瞬态服务时都会创建该服务的实例。AddScoped()-此方法创建作用域服务。的新实例作用域内的每个请求创建一次作用域服务。对于例如,在web应用程序中,它为每个http创建一个实例请求,但在同一调用中的其他调用中使用同一实例web请求。

当必须注入同一类型的多个对象时,ASP.NET MVC核心DI(依赖注入)中的瞬时、作用域和单例定义对象创建过程。如果你是依赖注入的新手,你可以看到这个DI-IoC视频。

您可以看到下面的控制器代码,其中我在构造函数中请求了两个“IDal”实例。Transient、Scoped和Singleton定义了同一个实例是否将以“_dal”和“_dal1”或不同的方式注入。

public class CustomerController : Controller
{
    IDal dal = null;

    public CustomerController(IDal _dal,
                              IDal _dal1)
    {
        dal = _dal;
        // DI of MVC core
        // inversion of control
    }
}

瞬态:在瞬态中,将在单个请求和响应中注入新的对象实例。下面是我显示GUID值的快照图像。

作用域:在作用域中,相同的对象实例将被注入到单个请求和响应中。

Singleton:在Singleton中,将在所有请求和响应中注入相同的对象。在这种情况下,将创建对象的一个全局实例。

下面是一个简单的图表,直观地解释了上述基本原理。

上图是我在孟买参加ASP.NET MVC培训时,SBSS团队绘制的。非常感谢SBSS团队创建了上述图像。