Обработка исключений при использовании внедрения зависимостей в C # 4.0 - PullRequest
6 голосов
/ 11 ноября 2011

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

Допустим, я хочу использовать конструктор инъекций в моем приложении. Так, например, у меня будет что-то вроде этого:

public class FileDataProvider : IDataProvider
{
    public MyData GetData()
    {
        // Get data from a file
    }
}

public class DatabaseDataProvider : IDataProvider
{
    public MyData GetData()
    {
        // Get data from a database
    }
}

public class DataReader : IDataReader
{
    private IDataProvider dataProvider;

    public DataReader(IDataProvider dataProvider)
    {
        this.dataProvider = dataProvider;
    }

    public void OutputData()
    {
        MyData data = dataProvider.GetData();
        Console.WriteLine("{0}", data.ToString());
    }
}

Если я использую инъекцию конструктора, я по определению не имею ни контроля, ни представления о конкретном экземпляре класса, реализующего IDataProvider, который будет внедрен в мой класс DataReader. Это означает, что в моем классе DataReader я не знаю, что происходит в методе GetData, включая тот факт, что я не знаю, может ли оно вызвать исключение или нет, и если да, то какого рода исключение.

В моем методе OutputData я должен обернуть мой код в блок try {} catch {} и если да, то какое исключение я должен перехватить? Если я ловлю IOException или SQLException или на самом деле , любое исключение какого-либо типа означает, что я заранее понимаю, каким образом IDataProvider может / должен быть реализован. Я не думаю, что это хорошо. Я также мог бы вставить XMLDataProvider или NetworkResourceDataProvider. Но в то же время я должен обработать исключения в какой-то момент.

Мой вопрос: как правильно обрабатывать исключения и регистрировать, что происходит в приложении, использующем инверсию управления в целом и инжекцию в конструктор более конкретно? Кроме того, каков правильный путь - если таковой имеется - для создания исключений в классе, который реализует интерфейс?

-

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

Ответы [ 3 ]

6 голосов
/ 11 ноября 2011

По определению, если вы не знаете, как обрабатывать исключение, не отлавливайте его. Период.

6 голосов
/ 11 ноября 2011

По моему мнению, конкретные реализации IDataProvider должны перехватывать соответствующие исключения (ввод-вывод для файлового повидера, SQL для поставщика БД) и вызывать другое исключение, которое сообщает об общей ошибке получения данных, то есть DataProviderException.При необходимости вы можете сохранить исходное исключение как свойство внутреннего исключения, чтобы информация не терялась.

При этом способе потребитель DataReader должен обрабатывать только это конкретное исключение и защищаться от деталей.Это предполагает, что потребитель имеет способ обработки исключения, т.е. возможна повторная попытка.

5 голосов
/ 11 ноября 2011

Позвольте мне начать с того, что ваш английский намного лучше моего французского, поэтому t'inquietes pas de ca.

Вы не собираетесь делать что-то особенное в этом пункте кода, если произойдет исключение SQLException, верно?

В общем, вы не хотите ловить исключение, пока не знаете, что с ним делать.Исключения, как правило, служат для того, чтобы дать разработчикам возможность узнать, что пошло не так: именно поэтому вы получаете трассировку стека, чтобы согласиться с ними.Поэтому, как правило, лучше позволить им всплывать до точки прямо под пользовательским интерфейсом, где вы можете регистрировать их и изящно сообщать пользователю, что произошло что-то неожиданное.

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