Avatar billede md_craig Nybegynder
13. oktober 2006 - 14:14 Der er 8 kommentarer og
1 løsning

ExceptionFormaters med arv og generics, problemmer

Hej...

Jeg har et projekt hvor jeg har lavet noget der hedder en ExceptionFormatter, meningen er at den skal stå for at formatere en given Exception på en specifik måde i forhold til hvilket type det er, og så ned i en log fil...

Dette er lavet således at man har en Base klasse ExceptionFormatter der indeholder en metode Format, som så tager en Exception og en StringWriter.

Meningen er så at man kan nedarve fra denne klasse, fx SqlExceptionFormatter, som istedet for at tage en Exception, så tager en SqlException naturligvis og giver en unik formatering får SqlExceptions.

Over i min Log klasse, har jeg så en metode der heder WriteException, som tager en Exception af en given art, og så en ExceptionFormatter...

På den måde er det meningen at man senere ved at arve fra ExceptionFormatter kan lave andre former for Formatters til andre former for exceptions....

Alt dette fungerede egentlig meget fint, indtil at jeg mente at der skulle introduceres Typestærke Formatters...

for som det ser ud nu så tager metoden i en SqlExceptionFormatter stadigvæk vare en alm. Exception og forsøger at formatere den... dette kan naturligvis ordnes med noget cast osv. men jeg ville gerne symbolicere ud af til at en SqlException formatter altså kun kunne tage en SqlException...

Det jeg så har gjort er at jeg i min Exception formatter klasse har tilføjet generics som følger:

public class ExceptionFormatter<TException> where TException : Exception

nu skulle jeg jo så gerne kunne arve fra min ExceptionFormatter således:

public class SqlExceptionFormatter : ExceptionFormatter<SqlException>

Og det virker sådan set også fint... lige indtil vi kommer til min WriteMetode på min Log klasse som ser således ud:

public static void WriteException( Exception ex, ExceptionFormatter formatter )

Dette er jo klart forkert, da jeg jo vil have sin typedefinering som fx:

public static void WriteException( Exception ex, ExceptionFormatter<Exception> formatter )

Men den er jeg jo sådan set ikke interesseret i på dette tidspunkt, for metoden her skal jo kunne tage alle former for ExceptionFormatters, og deres tilhørende Exceptions...

så den brokker sig jo straks over at jeg fx prøver at give den en:

Log.WriteException( ex, new SqlExceptionFormatter() );

Øhhh.... det kan godt være det sådan lige er lidt svært at forstå helt hvad det er jeg vil... men spørg... mens så tænker jeg lige over om jeg måske kan udybe det lidt mere...

Og det er slet ikke sikkert man kan det jeg gerne vil jo...
Avatar billede md_craig Nybegynder
13. oktober 2006 - 14:18 #1
ExceptionFormatter
-------------------------------------------------------------------------------------
    public class ExceptionFormatter<TException>
        where TException : Exception
    {
        #region public ExceptionFormatter()
        /// <summary>
        ///
        /// </summary>
        public ExceptionFormatter()
        {
        }
        #endregion

        #region public virtual void Format( TException ex, StringWriter writer )
        /// <summary>
        ///
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="writer"></param>
        public virtual void Format( TException ex, StringWriter writer )
        {
            writer.WriteLine( string.Format( "  ->  Message: {0}...", ex.Message ) );
            foreach ( string line in ex.StackTrace.Split( new string[] { "\n\r", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries ) )
                writer.WriteLine( string.Format( "  ->    {0}...", line ) );
        }
        #endregion
    }
-------------------------------------------------------------------------------------

SqlExceptionFormatter
-------------------------------------------------------------------------------------
    public class SqlExceptionFormatter : ExceptionFormatter<SqlException>
    {
        /// <summary>
        ///
        /// </summary>
        public SqlExceptionFormatter()
            : base()
        {
        }

        #region public override void  Format(SqlException ex, StringWriter writer)
        /// <summary>
        ///
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="writer"></param>
        public override void  Format(SqlException ex, StringWriter writer)
        {
            writer.WriteLine( string.Format( "  ->  SQL:Class {0}", ex.Class ) );
            writer.WriteLine( string.Format( "  ->  SQL:ErrorCode {0}", ex.ErrorCode ) );
            writer.WriteLine( string.Format( "  ->  SQL:State {0}", ex.State ) );

            base.Format( ex, writer );
        }
        #endregion
    }
-------------------------------------------------------------------------------------
Avatar billede md_craig Nybegynder
13. oktober 2006 - 14:20 #2
Log: Write Exception Metode
-------------------------------------------------------------------------------------
    #region public static void WriteException( Exception ex, ExceptionFormatter formatter )
        /// <summary>
        ///
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="formatter"></param>
    public static void WriteException( Exception ex, ExceptionFormatter<Exception> formatter )
    {
      //...
    }
    #endregion
-------------------------------------------------------------------------------------
Avatar billede arne_v Ekspert
14. oktober 2006 - 04:39 #3
public static void WriteException<TException> ( TException ex, ExceptionFormatter<TException> formatter ) where TException : Exception
{
...
}

og

Log.WriteException<SqlException>( ex, new SqlExceptionFormatter() );

bør compile
Avatar billede arne_v Ekspert
14. oktober 2006 - 04:51 #4
iøvrigt foretrækker de fleste kun 1 linie per log entry
Avatar billede md_craig Nybegynder
16. oktober 2006 - 11:55 #5
Hmmm... bare lidt træls man så skal fortælle den hvad det er, kan godt være jeg bare holder mig til det som det er nu så, må jeg lige se på...

Og at det fleste foretrækker 1 linie pr. entry, det må de fleste om...

Meningen med det her er at lave et flexibelt framework til en Log, så de formatters kan laves efter eget ønske, der er jo ikke nogen der siger man ikke godt må lave sin egen MyOwnPersonalSqlExceptionFormatter, det er netop hele ideen at man kan...

Men når jeg skal bruge de logs til at Debugge osv... så skal de Exceptions og deres stactraces nu være til at læse i filen... derfor bliver der flere linier...

Senere er målet at man også kan skrive til forskelige former for "lager".. altså forskellige log writers så man kan logge i en Database, i Windowses event log, en FlatFile eller hvad man lyster... alt i alt... så et flexibelt framework som muligt... og som stadig er simpelt...
Avatar billede arne_v Ekspert
18. oktober 2006 - 03:14 #6
istedetfor at sende en formatter med - kunne du så ikke registrere formatter
til de forskellige exceptions ?
Avatar billede md_craig Nybegynder
18. oktober 2006 - 10:01 #7
Nej... for meningen er sådan set at hvis man ikke angiver en ExceptionFormatter, så skal der anvendes en basis formatter uanset hvilken type Exception det så er.

Der er en række Overloads på WriteException som fx ikke tager en Formatter med som parameter, kaldes disse skal en Basis Formatter bare bruges, og ikke den der måske logisk ville tilhører den givne Exception...

Meningen med SqlExceptionFormatteren fx, er bare at tilbyde nogle standard-specifikke formatters... og det er ikke meningen at den skal bruges oven på alle SqlExceptions man får ind nødvendigvis
Avatar billede md_craig Nybegynder
07. november 2006 - 12:01 #8
Nå men uanset hvad, jeg gik fra alt med Generics, men derfor kunne det stadig godt have været en løsning, så smid et svar
Avatar billede arne_v Ekspert
10. november 2006 - 04:11 #9
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester