управление сферой больших зависимостей в ninject - PullRequest
1 голос
/ 14 ноября 2011

У меня есть класс, который управляется ninject как синглтон, который выглядит примерно так:

class InMemoryDb
{
    IInitialiser _initialiser;
    SomeBackingStore _store;

    InMemoryDb(IInitialiser initialiser)
    {
        _initialiser = initialiser;
    }

    void Init()
    {
        //once init'd i don't care what happens to the _initialiser field
        _store = _initialiser.Initialise();
    }
}

У меня есть IInitialiser, поддерживаемый через Ioc (на самом деле все управляется контейнером).Моя проблема заключается в том, что после инициализации объект _initialiser никогда не собирается сборщиком мусора (и зачем это делать, если технически на него все еще ссылается одноэлементный объект InMemoryDb), и он находится в памяти приложения, потребляющей более 5 гигабайт.Как я могу аккуратно структурировать свой код, чтобы мои объекты по-прежнему подключались через Ioc и удалялись после использования.По сути, как только он инициализирован, я могу быть уверен, что его можно безопасно утилизировать.

К сожалению, я до сих пор прибегаю к:

void Init()
{
    _store = new Initialiser().Initialise();
}

Это в конечном итоге будет очищеноGC как таковой выходит из области видимости, как только метод Init () завершает выполнение, но это делает мой код непроверенным и имеет запах этого.Я также подумал о том, чтобы сделать:

void Init()
{
    _store = SericeLocator.Get<IInitialiser>().Initialise();
}

Но опять же, это не идеально, так как это увеличивает мой код вызовом ServiceLocator.

Есть предложения о том, как это лучше структурировать?

1 Ответ

2 голосов
/ 14 ноября 2011

Поскольку только метод Init требует инициализатора, было бы более целесообразно, чтобы этот метод принимал его в качестве аргумента вместо использования конструктора:

class InMemoryDb
{
    SomeBackingStore _store;

    void Init(IInitialiser initialiser)
    {
        _store = initialiser.Initialise();
    }
}

Тогда вызывающий метода Init отвечает за предоставление инициализатора. Вы также можете использовать логическое поле isInitialized, которое будет указывать, был ли вызван метод Init. Это поле будет использоваться другими методами, которые потенциально полагаются на поле _store для обеспечения его правильной инициализации.

...