Что является достойным способом внедрения зависимости в одноэлементный класс? - PullRequest
5 голосов
/ 26 мая 2011

У меня есть синглтон, который зависит от другого класса, поэтому я бы хотел внедрить эту зависимость, чтобы сделать ее тестируемой модулем.Поскольку нет способа использовать инжекцию конструктора в синглтоне, я полагаю, что вместо этого я должен использовать установку сеттера, но мне это действительно не нравится, поскольку в какой-то момент кто-то (вероятно, я) забудет вызвать сеттер.Конечно, вы можете добавить зависимые объекты в метод getInstance синглтона, но это тоже довольно уродливо.Есть ли более эффективные способы решения этой проблемы (без использования таких инструментов, как контейнеры IoC)?

public class Singleton {
    private ISomeDependency _dependency;
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {
    }
    public static Singleton getInstance() {
       return INSTANCE;
    }
    ...
}

Ответы [ 2 ]

3 голосов
/ 26 мая 2011

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

Просто внедрите экземпляр этого типа в качестве конструктора в типы, которые зависят от него, и все готово. Это дает вам возможность построить граф объектов в верхней части вашего приложения, контролировать образ жизни и внедрять зависимости в этот экземпляр.

Дизайн этого класса должен быть таким же, как и у любого другого класса:

public class SomeService : ISomeService 
{
    private ISomeDependency _dependency;

    public ISomeService(ISomeDependency dependency)
    {
        _dependency = dependency;
    }

    // ISomeService members here
}

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

0 голосов
/ 26 мая 2011

Вы можете использовать контейнер ввода зависимостей (например, Spring.Net , MS Unity и т. Д.), Чтобы получить конкретный тип вашей зависимости.

public class Singleton {
private ISomeDependency _dependency = Container.Resolve<ISomeDependency>();
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
   return INSTANCE;
}
...
}

Теперь у вас есть контроль за пределами синглтона.

...