не решаемая задача - как сделать единую обёртку для разных вызовов?

OldWoker
Дата: 15.01.2010 12:35:20
Привет всем! М.б. кто то видел идей на сл. тему. Есть класс c

class GetData
{
private Chanel _client  = new Chanel();

public MyData1 GetMyData1()
(

  // надо окружить вызов try  catch
   return _client.GetMyData1()
)

public MyData2 GetMyData2(int par1, string par2)
(
// надо окружить вызов try  catch
   return _client.GetMyData2(par1, par2)
)
}

Таких разнотипных вызовов м.б. очень много, каждый вызов нужно окружить достаточно длинным анализом Exception которые могут возникнуть. Вопрос - можно ли сделать класс обёртку где обработки всех разнотипных вызовов будут в одном месте с одним анализом всех Exception?
Andrew1411
Дата: 15.01.2010 12:57:19
OldWoker,

Почему не подходит статический метод (метод расширитель) для обработки?
OldWoker
Дата: 15.01.2010 13:08:52
Andrew1411
OldWoker,

Почему не подходит статический метод (метод расширитель) для обработки?

все вызовы разнотипны! Как в этом случае написать - покажите?
Курочка Ряба
Дата: 15.01.2010 13:24:48
OldWoker
каждый вызов нужно окружить достаточно длинным анализом Exception которые могут возникнуть.

Что будет являться признаком генерации того или иного исключения?

P.S. Например, признаком может являться возвращаемый тип класса. Но, если у Вас будет несколько методов, возвращаемых один и тот же класс - для них все исключения будут одинаковы, как Вы понимаете.

Итак, сначала определитесь с признаком, потом будет крутить педали лисапеда.
Курочка Ряба
Дата: 15.01.2010 13:54:03
Вот пример для обёртки вызовов, где признаком является класс.

Классы метим интерфейсом для последующего определения:

+ Entity classes
public interface Entity
{

}

public class MyData1 : Entity
{
    public int MyMethod1;

    public MyData1(int myMethod1)
    {
        MyMethod1 = myMethod1;
    }
}

public class MyData2 : Entity
{
    public int MyMethod2_0;
    public int MyMethod2_1;

    public MyData2(int myMethod2_0, int myMethod2_1)
    {
        MyMethod2_0 = myMethod2_0;
        MyMethod2_1 = myMethod2_1;
    }
}


Сама поставка классов:

+ Chanel
public class Chanel
{
    public MyData1 GetMyData1(int myMethod1)
    { 
        return new MyData1(myMethod1);
    }

    public MyData2 GetMyData2(int myMethod2_0, int myMethod2_1)
    { 
        return new MyData2(myMethod2_0, myMethod2_1);
    }
} 


Внешняя обертка с логикой генериации Exception:

+ GetData
public class GetData
{
    private Chanel _client  = new Chanel();

    public Exception MapException<T>(Exception ex) where T : Entity
    {
        string text = string.Empty;

        if (typeof(T) == typeof(MyData1))
        {
            text = "Косяки с MyData1";
        }
        else if (typeof(T) == typeof(MyData2))
        {
            text = "Косяки с MyData2";
        }
        else 
        {
            text = "Косяки хз какие";
        }


        return new Exception(text, ex);
    }

    public MyData1 GetMyData1(int myMethod1)
    {
        try
        {
            //throw new Exception("Опачки!"); // Произошла ашипко
            return _client.GetMyData1(myMethod1);
        }
        catch (Exception ex)
        {
            MapException<MyData1>(ex);
        }

        return null;
    }

    public MyData2 GetMyData2(int myMethod2_0, int myMethod2_1)
    {
        try
        {
            //throw new Exception("Опца-ца!"); // Произошла ашипко
            return _client.GetMyData2(myMethod2_0, myMethod2_1);
        }
        catch (Exception ex)
        {
            MapException<MyData2>(ex);
        }

        return null;
    }
}


P.S. Если признак - что-то другое, выделяйте это "другое" в некие контейнеры-классы, помечайте предком (или интерфейсом) и вперёд. Ифов и свитчей не избежать, так как, насколько я понял, исключение выдаются определенные (для каждого признака свои).
Sargos
Дата: 15.01.2010 15:38:01
А что обработчик исключения по умолчанию для приложения не подходит?
OldWoker
Дата: 15.01.2010 15:38:30
Курочка Ряба
Вот пример для обёртки вызовов, где признаком является класс.

Классы метим интерфейсом для последующего определения:

+
+ Entity classes
public interface Entity
{

}

public class MyData1 : Entity
{
    public int MyMethod1;

    public MyData1(int myMethod1)
    {
        MyMethod1 = myMethod1;
    }
}

public class MyData2 : Entity
{
    public int MyMethod2_0;
    public int MyMethod2_1;

    public MyData2(int myMethod2_0, int myMethod2_1)
    {
        MyMethod2_0 = myMethod2_0;
        MyMethod2_1 = myMethod2_1;
    }
}


Сама поставка классов:

+
+ Chanel
public class Chanel
{
    public MyData1 GetMyData1(int myMethod1)
    { 
        return new MyData1(myMethod1);
    }

    public MyData2 GetMyData2(int myMethod2_0, int myMethod2_1)
    { 
        return new MyData2(myMethod2_0, myMethod2_1);
    }
} 


Внешняя обертка с логикой генериации Exception:

+
+ GetData
public class GetData
{
    private Chanel _client  = new Chanel();

    public Exception MapException<T>(Exception ex) where T : Entity
    {
        string text = string.Empty;

        if (typeof(T) == typeof(MyData1))
        {
            text = "Косяки с MyData1";
        }
        else if (typeof(T) == typeof(MyData2))
        {
            text = "Косяки с MyData2";
        }
        else 
        {
            text = "Косяки хз какие";
        }


        return new Exception(text, ex);
    }

    public MyData1 GetMyData1(int myMethod1)
    {
        try
        {
            //throw new Exception("Опачки!"); // Произошла ашипко
            return _client.GetMyData1(myMethod1);
        }
        catch (Exception ex)
        {
            MapException<MyData1>(ex);
        }

        return null;
    }

    public MyData2 GetMyData2(int myMethod2_0, int myMethod2_1)
    {
        try
        {
            //throw new Exception("Опца-ца!"); // Произошла ашипко
            return _client.GetMyData2(myMethod2_0, myMethod2_1);
        }
        catch (Exception ex)
        {
            MapException<MyData2>(ex);
        }

        return null;
    }
}


P.S. Если признак - что-то другое, выделяйте это "другое" в некие контейнеры-классы, помечайте предком (или интерфейсом) и вперёд. Ифов и свитчей не избежать, так как, насколько я понял, исключение выдаются определенные (для каждого признака свои).



Собственно моя задача - рефракторинг существующего кода. Есть куча классов ( все от одного базового) в каждом куча вызовов без try cath. Известно при вызове этих методов возможны (кроме выполнения) около 20 типов Exception, надо сделать так что бы в случае Excpetion конечный пользователь понимал что надо сделать ( типа "Сервер занят позвоните позднее!") вот и всё. Так что единственный пока выход это окружить вызовы
try
            {
                return _chanal.GetMyData(.....);
            }
            catch (Exception err)
            {
                ParseError(err); // здесь анализ
                return null;
            }


всё спасибо - тема закрыта
Курочка Ряба
Дата: 15.01.2010 16:08:15
OldWoker
Так что единственный пока выход это окружить вызовы
try
            {
                return _chanal.GetMyData(.....);
            }
            catch (Exception err)
            {
                ParseError(err); // здесь анализ
                return null;
            }


Ну так я об этом и написал :)

OldWoker
всё спасибо - тема закрыта

Ок.