Инъекция в конструктор c # и перегрузки конструктора - PullRequest
2 голосов
/ 02 июня 2011

Я впервые использую инъекцию в конструктор и хочу написать мой код для защиты.

Поэтому, если у меня есть класс с конструктором и методом сохранения, как показано ниже:

public SomeConstructor(string name, Object someObject)
{
  _name= name;
  _someObject= someObject;
}

public void Save()
{
  // Does a database save
}

Но тогда нужно создать еще один связанный метод в этом классе, которому не нужен _someObject, поэтому я создаю перегруженный цепочечный конструктор как:

public SomeConstructor(string name) : this(name, null)
{
}

Как я могу успешно остановить создание экземпляра класса с помощью этого второго конструктора с 1 параметром и с помощью Save (), у которого someObject имеет значение null?

Я не использую инъекционный инструмент.

Выше приведен простой пример, и в нем вы правы. Я мог бы просто сгенерировать исключение для нуля, как если бы не было установлено свойство.

Чего я хотел избежать, так это серии проверок в начале каждого метода.

Ответы [ 4 ]

4 голосов
/ 02 июня 2011

Используйте трение, которое вы испытываете, как систему предупреждения .Это действительно говорит вам о том, что вы, вероятно, движетесь к низкой сплоченности и нарушению принципа одиночной ответственности .

Если это так, выполните рефакторинг класса в дваотдельные классы.

1 голос
/ 02 июня 2011

Вы можете предотвратить эту ситуацию с помощью исключения времени выполнения, такого как InvalidOperationException.

Если некоторые экземпляры класса создали конструктор с двумя параметрами и пытаются вызвать Save, просто проверьте, имеет ли значение someObject значение null, и если это так:

throw new InvalidOperationException("This method cannot be invoked in current object state");

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

0 голосов
/ 02 июня 2011

IoC - это просто способ динамически разрешить зависимость, но не решает никаких проблем с ОО.Я бы сконцентрировался на хорошем дизайне ОО вместо того, чтобы попытаться найти способ обмануть фреймворк, заставляя использовать подрядчика вместо другого. Вопрос в том, как бы вы это сделали, если бы не использовали фреймворк IoC?вероятная проверка, является ли SomeObject нулевым?

0 голосов
/ 02 июня 2011
public void Save()
{  
    if (_someObject == null)
        throw new InvalidOperationException();
}

Полагаю, это очевидно. Но вы действительно не можете создать контракт, в котором тип строится иначе, если вы не измените свой тип SomeConstructor, чтобы он работал как шаблон декоратора . Что делает шаблон декоратора, так это то, что он позволяет вам строить иерархию наследования во время выполнения, а не во время компиляции.

Затем вы можете создавать разные объекты в зависимости от того, какие операции разрешены внутри. Это некоторая работа для чего-то, что может быть легко обработано с предварительным условием для метода Save. Но, возможно, это то, что вам нужно. И если бы вы сделали это, вы могли бы оговорить свой контракт в конструкторе SomeConstructor.

Вот пример:

interface ISomeConstructor
{
    void Save();
}

class SomeConstructor
{
    ISomeConstructor impl;

    public SomeConstructor(string name, object someObject)
    {
        impl = new StringAndObject(name, someObject);
    }

    public SomeConstructor(string name)
    {
        impl = new JustString(name);
    }

    public void Save()
    {
        impl.Save();
    }
}

Типы StringAndObject и JustString реализуют ISomeConstructor, и они могут обрабатывать метод Save по своему усмотрению.

Это небольшое изменение шаблона декоратора, так как обычно вы ожидаете, что ISomeConstructor будет также передан в качестве аргумента конструктору.

...