Дублирование кода в веб-потребление услуг


У меня есть набор классов, абстрагирующих звонки на набор веб-служб. У меня 6 классов в данной группе, 4 из которых содержат простую функцию, которая при малых, по-прежнему повторяются. Что происходит, заключается в том, что если какое-то исключение или нарушение бизнес-правил происходит на службе, они упаковывают его в качестве объекта ошибка в ответе. В противном случае, объект fault имеет значение null. Как следствие, функций просто проверить, если этот объект не является нулем, и, если да, то причина указана и исключение по цепочке. Так что в одном классе, он может выглядеть

private void ThrowIfContainsFault(AlphaResponse response)
{
    if (response.Fault != null)
    {
        throw new WhateverException(response.Fault.reasonText);
    }
}

И тогда другие классы, реакция объекта будет другого типа, но разлома собственность же и блок кода один и тот же.

private void ThrowIfContainsFault(BravoResponse response)
private void ThrowIfContainsFault(CharlieResponse response)
private void ThrowIfContainsFault(DeltaResponse response)

(Примечание: эти имена классов изменен для удобочитаемости, у них нет общего предка для этих объектов ответа.)

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

Вот мой никчемный думал, что я даже не уверен, что мне нравится:

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

internal interface IFaultThrower
{        
}

internal static class IFaultThrowerExtension
{
    internal static void ThrowIfNotNull(this IFaultThrower thrower, Fault fault)
    {
        if (fault != null)
        {
            throw new WhateverException(fault.reasonText);
        }
    }
}

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

 // this.ThrowIfContainsFault(response);
 this.ThrowIfNotNull(response.Fault);

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



325
2
c#
задан 19 августа 2011 в 04:08 Источник Поделиться
Комментарии
2 ответа

Я думаю, что это плохая идея, чтобы ввести пустой интерфейс просто добавить метод расширения к нему. Вы должны думать о интерфейс как контракт, а не просто способ ввести синтаксис сахара :)

Я считаю, что вместо того, чтобы играть с методов расширения, для этого достаточно ввести отдельный, вспомогательный, внутренний класс, единственной целью которого будет бросать исключение, если объект имеет значение null ошибка:

    internal class FaultResponseChecker
{
internal static void ThrowIfNotNull(Fault fault)
{
if (fault != null)
{
throw new WhateverException(fault.reasonText);
}
}
}

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

1
ответ дан 20 августа 2011 в 08:08 Источник Поделиться

Если AlphaResponse, BravoResponse и все наследует интерфейс "сайта iresponse" то вы можете сделать это.

internal static class FaultThrowerExtension
{
internal static void ThrowIfContainsFault<T>(this T response) where T : IResponse
{
if (response.Fault != null) throw new WhateverException(fault.reasonText);
}
}

Обновление :
После прочтения вашего комментария, что они не имеют общего интерфейса, то вы могли бы сделать это.
Это намного больше, messey.

internal static class FaultThrowerExtension
{
internal static void ThrowIfContainsFault<T>(this T response) where T : class
{
var type = typeof(T).FullName;

foreach (var propertyInfo in PropertyInfoCache[type])
{
if (propertyInfo.Name == "Fault")
{
var fault = propertyInfo.GetValue(value, null);
if (response.Fault != null) throw new WhateverException(fault.reasonText);
}
}
}
}

0
ответ дан 19 августа 2011 в 06:08 Источник Поделиться