Контейнер IoC и управление памятью DLL - PullRequest
0 голосов
/ 28 мая 2019

Я работаю над проектом сервера, и на сервере есть несколько разных независимых слоев и несколько классов-одиночек. И я использую SimpleInjector, контейнер IoC, по всем слоям. Полный, исполняемый пример исходного кода доступен по адресу https://github.com/DamonJung/TestAdvanture001.. ( Это неоправданно долго, потому что я пытался воспроизвести там другую проблему. )

Я обращаюсь к методу Singleton из Main прямо или косвенно из контейнера IoC.

// Use case in Main
.
.
using Impl;    

static void Main(string args[])
{
    .
    .
    // Singleton.Instance address = 0x0301f001 for example.
    var context = Singleton.Instance.GetContext();

    // SimpleInjector
    // Singleton.Instance address inside of the dependency = 0x0408f023 for example.
    var di = Container.GetInstance<ISomeInterface>();
    var contextFromIoC = di.GetContext();
    .
    .
}

Я ожидал, что Singleton должен быть создан только один раз, и статический экземпляр должен иметь точно такой же адрес памяти в приложении, независимо от того, откуда он вызывается и как бы он ни создавался (Main или IoC контейнер)

Однако, как говорится в выводе консоли, это не сработало. Singleton Instance не должен был создаваться более одного раза. Но в итоге у них был другой адрес.

enter image description here

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

Не является ли это подтверждением факта о статических переменных, не так ли?

Статические члены

Нестатический класс может содержать статические методы, поля, свойства или события. Статический член вызывается в классе, даже если экземпляр класса не создан. Статический член всегда доступен по имени класса, а не по имени экземпляра. Существует только одна копия статического члена, независимо от того, сколько экземпляров класса создано . Статические методы и свойства не могут получить доступ к нестатическим полям и событиям в их содержащем типе, и они не могут получить доступ к переменной экземпляра любого объекта, если она явно не передана в параметре метода.

Я искал соответствующую прочитанную в SimpleInjector's документацию и не нашел ничего. Чтение о динамической компоновке библиотеки и ее управлении памятью не подходит мне (я буду читать ее снова и снова и снова!)

  • Как программа обращается с dll с точки зрения управления памятью
  • Если контейнер IoC является сценой позади, как SimpleInjector обрабатывает зависимости, когда они регистрируются через Container.Register();

Выше всего были бы мои главные вопросы.

1 Ответ

4 голосов
/ 28 мая 2019

Два экземпляра созданы, потому что ваш код создает два экземпляра.

Первый создается с помощью следующего кода

public class Singleton
{
    public static readonly Singleton Instance = new Singleton();
    // ....
}

, а второй создается при регистрации вашего типа в SimpleInjector

Если вы хотите экземплярчтобы быть созданным только один раз, вы можете использовать приватный конструктор

public class Singleton
{
    static Singleton()
    {
        Singleton.Instance = new Singleton();
    }
    public static Singleton Instance { get; }

    private Singleton(){ 
    }
}

Таким образом, только класс Singleton создает себя.

Чтобы зарегистрировать ваш синглтон в SimpleInjector, вы можете использовать RegisterInstanceМетод:

container.RegisterInstance<Singleton>(Singleton.Instance);

Кстати, более распространено позволить контейнеру самостоятельно управлять экземплярами, а не полагаться на статическое свойство, которое может указывать на то, что вы используете сервисный локатор , которыйобщий анти-шаблон.

Если вы хотите, чтобы SimpleInjector управлял экземпляром, вы должны использовать

container.RegisterSingleton<Singleton>();

Таким образом SimpleInjector создаст только один Singleton экземпляр для контейнера.

См. Образ жизни синглтона в SimpleInjector документации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...