Синглтон в ASP.NET Ядро допускает несколько экземпляров

#asp.net-core #dependency-injection #singleton

#asp.net-ядро #внедрение зависимостей #синглтон

Вопрос:

Я реализовал очень простой код для проверки функциональности внедрения зависимостей в ASP.NET Ядро 2.1.

К сожалению, я получил другие результаты, как и ожидал. Каждый раз, когда я обновляю сайт, я получаю другой идентификатор вместо того же самого.

Startup.cs

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

HomeController.cs

 public class HomeController : Controller
{
    private IPerson _person;

    public HomeController( IPerson person)
    {
        _person = person;
    }

    public ViewResult Index()
    {
        return View( "Index", $"{_person.id}");
    }
}
  

Person.cs

 public interface IPerson
{
    string id { get; }
}

public class Person : IPerson
{
    public string id => Guid.NewGuid().ToString();
}
  

Я подозреваю, что причина очень проста, но на самом деле не понимаю, что я сделал не так.

Ответ №1:

Я считаю, что проблема в том, как вы определили Id свойство в своем Person классе:

 public class Person : IPerson
{
    public string id => Guid.NewGuid().ToString();
}
  

Это означает: каждый раз, когда код запрашивает id — он получает вновь созданный идентификатор Guid — поэтому, конечно, вы продолжаете получать новые / разные идентификаторы Guid каждый раз, когда смотрите на своего человека!

Вам нужно получить один id раз — в Person конструкторе — и затем вернуть это:

 public class Person : IPerson
{
    private string _id;

    public void Person()
    {
        _id = Guid.NewGuid().ToString();
    }

    public string id => _id;
}
  

Я почти уверен, что как только вы это сделаете, синглтон будет работать — вы продолжаете получать один и тот же экземпляр Person каждый раз, когда смотрите на него.

Ответ №2:

Person.id это свойство, определенное как свойство, основанное на выражении, которое возвращает новый идентификатор Guid при каждом вызове, поэтому, даже если это может быть один и тот же экземпляр, вызов Person.id будет каждый раз получать новое значение.

Для правильного тестирования определите класс как:

 public class Person : IPerson
{
  private string id;

  public Person()
  {
    this.id = Guid.NewGuid().ToString();
  }

  public string Id => this.id;
}
  

Теперь id поле будет инициализироваться при создании класса, и Id свойство должно возвращать одно и то же значение для каждого запроса.