Extract from the DRP … “Using an interface instead of InvokeMethod with Reflection”
We are told that InvokeMethod with Reflection is slow and that we should be using an interface. But how … the example ProcessData either calls ComplexReflection (using InvokeMethod) or SimpleReflection (using an interface).
#define Neptune
using System;
using System.Reflection;
using System.Runtime.Remoting;
using System.Globalization;
using System.Diagnostics;
namespace BBD.Drp.Remoting
{
[RefClass("BBD.Drp.Remoting.CalculationA.dll",
"BBD.Drp.Remoting.CalculationA",
false)]
public class RemoteObject : MarshalByRefObject
{
private DateTime dateTimeStart = DateTime.Now;
private DateTime dateTimeEnd;
private long processTime;
public RemoteObject()
{
}
public bool ProcessData ( double valueOne, double valueTwo,
out double result, out string description )
{
bool success = false;
result = 0;
description = "Unknown";
// Check our attributes
Attribute[] attrs = Attribute.GetCustomAttributes(typeof(RemoteObject));
foreach ( object attr in attrs )
{
if ( attr is RefClass )
{
if ( ((RefClass)attr).complex )
{
success = this.ComplexReflection ( ((RefClass)attr).name, ((RefClass)attr).cclass,
valueOne, valueTwo, out result, out description );
}
else
{
success = this.SimpleReflection ( ((RefClass)attr).name, ((RefClass)attr).cclass,
valueOne, valueTwo, out result, out description );
}
dateTimeEnd = DateTime.Now;
// Calculate difference between end and start in milliseconds
processTime = (long) ((TimeSpan)(dateTimeEnd - dateTimeStart)).TotalMilliseconds;
}
}
return ( false );
}
private bool ComplexReflection( string dll, string cclass,
double valueOne, double valueTwo,
out double result, out string description )
{
// init
double retCode;
result = 0;
description = "";
// Load DAO using reflection
Assembly assembly = Assembly.LoadFrom( dll );
// Load Type within Assembly
Type type = assembly.GetType( cclass, true, true );
CultureInfo culture = new CultureInfo( "en" );
// Create an instance of a type.
object[] argsConstructor = { "Add Calculation" };
object objectCalculator = null;
objectCalculator = type.InvokeMember( null,
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.CreateInstance, null, null,
argsConstructor, culture );
// Call Method
object[] arguments = { valueOne, valueTwo, result, description };
retCode = (double)type.InvokeMember( "Calculate",
BindingFlags.Instance
| BindingFlags.InvokeMethod
| BindingFlags.Public,
//| BindingFlags.NonPublic, // Needed to access private
null, objectCalculator, arguments, culture );
result = (double)arguments[2];
description = (string)arguments[3];
return true;
}
private bool SimpleReflection( string dll, string cclass,
double valueOne, double valueTwo,
out double result, out string description)
{
// init
double retCode;
result = 0;
description = "";
object[] argsConstructor = { "Add Calculation" };
// Load DAO using reflection
Assembly assembly = Assembly.LoadFrom( dll );
Type type = assembly.GetType( cclass, true, true );
ICalculator calc = (ICalculator)Activator.CreateInstance( type, argsConstructor );
retCode = calc.Calculate ( valueOne, valueTwo, out result, out description );
return true;
}
[Conditional("Neptune")]
private void Whatever ()
{
}
}
}
If you have a better way of solving the issue, please let us know.