tags:

views:

174

answers:

1

Hi,

I'm currently trying to create a ToString - extension method for FaultException, that can also deal with FaultException<>. The problem I have is, that I want to include the details without using reflection.

What I currently have is:

if (ex.GetType() == typeof(FaultException<>))
{
  var prop = ex.GetType().GetProperty("Detail");

  if (prop == null)
    return ex.ToString();

  object details = prop.GetValue(ex, null);
}

Any idea how I can access the "Detail"-property without relection, if I have an object of type FaultException?

tia Martin

+1  A: 

Well, what would you do with the Detail if you knew it's type anyway?

Because it's generic you would have to have a generic method and use MethodInfo.MakeGenericMethod using the T of the FaultException as the generic parameter. Since you won't know exactly what type it is at compile time, you'd have to code against it generically in some sense anyway.

As an example, here's a method I wrote to log fault details:

private static void WriteGenericFaultExceptionDetail<T>(FaultException faultException, StringBuilder faultDetailsBuilder)
{
    FaultException<T> faultExceptionWithDetail = (FaultException<T>)faultException;

    DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T));

    using(StringWriter writer = new StringWriter(faultDetailsBuilder))
    using(XmlWriter xmlWriter = XmlWriter.Create(writer))
    {
        dataContractSerializer.WriteObject(xmlWriter, faultExceptionWithDetail.Detail);
    }
}

And then I call it like so:

// NOTE: I actually cache this in a static field to avoid the constant method lookup
MethodInfo writeGenericFaultExceptionDetailMethodInfo = typeof(MyClass).GetMethod("WriteGenericFaultExceptionDetail", BindingFlags.NonPublic|BindingFlags.Static);

Type faultExceptionType = myFaultException.GetType();

writeGenericFaultExceptionDetailMethodInfo.MakeGenericMethod(faultExceptionType.GetGenericArguments()).Invoke(null, new object[] { myFaultException, myTraceBuilder })
Drew Marsh
as I planned to use the DataContractSerializer, I only need the object to get the type, and I don't need reflection then. I only need access to the Detail-getter without using reflection, but it seems that it is not possible
Martin Moser
Did you read my code, 'cause that's exactly what I'm doing. The faultExceptionType variable is exception.GetType() in my second sample and then you see I call GetGenericArguments on it and pass those in to MakeGenericMethod. I'll update the code to make it more obvious.
Drew Marsh
Yes I did read your code, but my point is that this is still using reflection, and I don't see any advantage to the code snippet I posted...
Martin Moser
One advantage my approach offers over simply using reflection is if the method you bake used other generics inside of it it would become strongly typed to T. The more important advantage though is that the generic method instances can be cached once you bake them for a certain type so you can just use a delegate to invoke them which provides much better performance than *constantly* using reflection.
Drew Marsh