instantiate a class using reflection issue

L

learning

Hi how can I instaltiate a class and call its method. the class has
non default constructor. all examples i see only with class of defatul
constructor. I am trying to pull the unit test out from the product
source code, but still want to execute them under nunit.

I am trying this idea on nunit sample source code. Here is my class
and the experiemental code: both money.cs and Imoney.cs is compiled to
cs_money.dll. then I create another console app that include
cs_money.dll and try to instantiate the money class at runtime. (code
in moneytestwithreflection.cs; the driver is program.cs.). I can see
the disassembler able to see the all the methods and constructor, so i
think i can use refelction to do the same thing. //excepton already
thrown here saying can;t find the constructor when I call
createinstance in TRYITOUT.CS. I have include all the source file
here.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Money.cs:
namespace NUnitApp.Samples.BigMoney
{

using System;
using System.Text;

/// <summary>A simple Money.</summary>
class Money: IMoney {

private int fAmount;
private String fCurrency;

/// <summary>Constructs a money from the given amount and
/// currency.</summary>
public Money(int amount, String currency) {
fAmount= amount;
fCurrency= currency;
}

/// <summary>Adds a money to this money. Forwards the request to
/// the AddMoney helper.</summary>
public IMoney Add(IMoney m) {
return m.AddMoney(this);
}

public IMoney AddMoney(Money m) {
if (m.Currency.Equals(Currency) )
return new Money(Amount+m.Amount, Currency);
return new MoneyBag(this, m);
}

public IMoney AddMoneyBag(MoneyBag s) {
return s.AddMoney(this);
}

public int Amount {
get { return fAmount; }
}

public String Currency {
get { return fCurrency; }
}

public override bool Equals(Object anObject) {
if (IsZero)
if (anObject is IMoney)
return ((IMoney)anObject).IsZero;
if (anObject is Money) {
Money aMoney= (Money)anObject;
return aMoney.Currency.Equals(Currency)
&& Amount == aMoney.Amount;
}
return false;
}

public override int GetHashCode() {
return fCurrency.GetHashCode()+fAmount;
}

public bool IsZero {
get { return Amount == 0; }
}

public IMoney Multiply(int factor) {
return new Money(Amount*factor, Currency);
}

public IMoney Negate() {
return new Money(-Amount, Currency);
}

public IMoney Subtract(IMoney m) {
return Add(m.Negate());
}

public override String ToString() {
StringBuilder buffer = new StringBuilder();
buffer.Append("["+Amount+" "+Currency+"]");
return buffer.ToString();
}
}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
IMoney.cs:
namespace NUnitApp.Samples.BigMoney
{

/// <summary>The common interface for simple Monies and MoneyBags.</
summary>
interface IMoney {

/// <summary>Adds a money to this money.</summary>
IMoney Add(IMoney m);

/// <summary>Adds a simple Money to this money. This is a helper
method for
/// implementing double dispatch.</summary>
IMoney AddMoney(Money m);

/// <summary>Adds a MoneyBag to this money. This is a helper
method for
/// implementing double dispatch.</summary>
IMoney AddMoneyBag(MoneyBag s);

/// <value>True if this money is zero.</value>
bool IsZero { get; }

/// <summary>Multiplies a money by the given factor.</summary>
IMoney Multiply(int factor);

/// <summary>Negates this money.</summary>
IMoney Negate();

/// <summary>Subtracts a money from this money.</summary>
IMoney Subtract(IMoney m);
}
}

MY TEst code:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TRYITOUT.CS

using System;
//using System.Collections.Generic;
//using System.Text;
using System.Reflection;
using NUnit.Framework;

namespace cs_money_test_blar
{
public class MoneyBagTestWithReflection
{
//Money
private Object f12CHF;
private Object f14CHF;
private Object f7USD;
private Object f21USD;
//MoneyBag
private Object fMB1;
private Object fMB2;

//[SetUp]
public void SetUP()
{
//jsut assume the dll is present for now
System.Reflection.Assembly assem =
System.Reflection.Assembly.LoadFrom(@"C:\testframework
\nunit\source\samples\csharp\money\bin\Debug\cs-money.dll");
//Create Type
System.Type typef14CHF =
assem.GetType("NUnitApp.Samples.BigMoney.Money",true);
//Type typeinfo = typeof(typef14CHF);
BindingFlags flags = BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.CreateInstance;
//Console.WriteLine("typefull name :{0} Constructors: {1},
another {2}",typeinfo,
typeinfo.GetConstructors(FlagsAttribute).length,
ConstructorInfo[] myctor = typef14CHF.GetConstructors();
//Console.WriteLine("cotor {0}, {1}", myctor[0],
myctor[1]);
object [] arg = new object[2];
arg[0] = 12;
arg[1] = "CHF";

f14CHF =
System.Activator.CreateInstance(typef14CHF,false,flags,null,arg,null,null);
System.Type typef12CHF =
assem.GetType("NUnitApp.Samples.BigMoney.Money",true);
//excepton already thrown here saying can;t find the constructor.
//f12CHF = System.Activator.CreateInstance(typef12CHF(12,
"CHF"));
System.Type typef7USD =
assem.GetType("NUnitApp.Samples.BigMoney.Money",true);
//f7USD = System.Activator.CreateInstance(typef7USD(7,
"USD"));
System.Type typef21USD =
assem.GetType("NUnitApp.Samples.BigMoney.Money", true);
//f21USD =
System.Activator.CreateInstance(typef21USD(21,"USd"));
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EntryPoint.cs:
using System;
using cs_money_test_blar;

namespace EntryDriver
{
class Program
{
static void Main(string[] args)
{
MoneyBagTestWithReflection myreflection = new
MoneyBagTestWithReflection();
myreflection.SetUP();
}
}
}
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

learning said:
Hi how can I instaltiate a class and call its method. the class has
non default constructor. all examples i see only with class of defatul
constructor. I am trying to pull the unit test out from the product
source code, but still want to execute them under nunit.

I am trying this idea on nunit sample source code. Here is my class
and the experiemental code: both money.cs and Imoney.cs is compiled to
cs_money.dll. then I create another console app that include
cs_money.dll and try to instantiate the money class at runtime. (code
in moneytestwithreflection.cs; the driver is program.cs.). I can see
the disassembler able to see the all the methods and constructor, so i
think i can use refelction to do the same thing. //excepton already
thrown here saying can;t find the constructor when I call
createinstance in TRYITOUT.CS. I have include all the source file
here.

class Money: IMoney {
public Money(int amount, String currency) {
TRYITOUT.CS

System.Reflection.Assembly assem =
System.Reflection.Assembly.LoadFrom(@"C:\testframework
\nunit\source\samples\csharp\money\bin\Debug\cs-money.dll");
System.Type typef14CHF =
assem.GetType("NUnitApp.Samples.BigMoney.Money",true);
BindingFlags flags = BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.CreateInstance;
object [] arg = new object[2];
arg[0] = 12;
arg[1] = "CHF";

f14CHF =
System.Activator.CreateInstance(typef14CHF,false,flags,null,arg,null,null);
System.Type typef12CHF =
assem.GetType("NUnitApp.Samples.BigMoney.Money",true);

Three questions:
1) Why is Monet class not public ?
2) Why not use Assembly CreateInstance ?
3) Why do you specify the name of the interface instead of the
name of the class you want to interface ?

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top