CSLA DataSafeReader and Mbunit Reflector

CSLA DataSafeReader and Mbunit Reflector

Old forum URL: forums.lhotka.net/forums/t/6699.aspx


Chris62 posted on Monday, March 30, 2009

Hi all, I hope this is the right place to post this, I'm currently building some test cases for production code, I'm using Gallio framework v3.0.5 and mbUnit v2.  I have some code that has an internal constructor and I'm trying to use the mbUnit Reflector to create an object.  The constructor takes a SafeDataReader as a parameter(and then reads from it to populate fields).  I created a second constructor to take a DataTableReader to act as a comparison(although the DataTableReader constructor won't go to production).  Currently the SafeDataReader is failing and the DataTableReader is passing(by passing/failing I mean when I try to create the object by passing those as parameters in the constructor).

I'm not 100% sure if I'm creating the SafeDataReader correctly.  My goal is to populate the SafeDataReader with known values, without having to go to the database, and then compare them with a bunch of asserts in the Gallio/mbunit framework.

Sample code below.
[Serializable()]
public class PhoneNumberInfo : ReadOnlyBase<PhoneNumberInfo>
{
    protected int _id;
    protected string _phone = String.Empty;

    public int ID { get { return _id; } }

    public string Phone { get { return _phone; } }
   
    // The classes are instatiated from factory
    internal PhoneNumberInfo(SafeDataReader dr)
    {
        _id = dr.GetInt32("ID");
        _phone = dr.GetString("PhoneNumber");
    }

    internal PhoneNumberInfo(DataTableReader rdr)
    {
        _id = rdr.GetInt32("ID");
        _phone = rdr.GetString("PhoneNumber");
    }
}

public static object CreatePhone()
{
    DataTable table = new DataTable();
    DataColumn id = new DataColumn("ID", Type.GetType("System.Int32"));
    DataColumn number = new DataColumn("PhoneNumber", Type.GetType("System.String"));
   
    table.Columns.Add(id);
    table.Columns.Add(number);
   
    string[] expressions = new string[2];
    expresions[0] = 1;
    expresions[1] = "1234567890";
   
    table.Rows.Add(BLOCKED EXPRESSION;

    // Reflector is from MbUnit.Framework.Reflection.Reflector namespace
    // this works correctly passing the DataTableReader
    object obj = Reflector.CreateInstance(GetAssemblyFullName("MyNameSpace.myDll.dll"), "MyNameSpace.myDll.PhoneNumberInfo", table.CreateDataReader());
   
    // this doesn't work correctly
    DbDataReader dbReader = table.CreateDataReader();
    dbReader.Read();
    SafeDataReader safeReader = new SafeDataReader(dbReader);
   
    // this fails passing the SafeDataReader
    object obj = Reflector.CreateInstance(GetAssemblyFullName("MyNameSpace.myDll.dll"), "MyNameSpace.myDll.PhoneNumberInfo", safeReader);

   return obj;
}
(the sample is a stripped down example of what I'm working on)

Am I missing something?

Chris62 replied on Wednesday, April 01, 2009

I was able to come up with a solution.
Create the table with the rows and column types as usual when building a DataTable.

DbDataReader dbReader = guest.CreateDataReader();
dbReader.Read();
SafeDataReader safeReader = new SafeDataReader(dbReader);

The key was to adjust the type to a DbDataReader(which I'm guessing both SqlDataReader & DataTableReader derive from), anyway, apparently the SafeDataReader will take a DbDataReader as a parameter.  I'm not sure why the .Read() method is necessary.

RockfordLhotka replied on Wednesday, April 01, 2009

You have to call Read() on a datareader to get it to the first row. It starts out just before the first row.

You can call Read() before or after creating the SafeDataReader. SafeDataReader also has a Read() method, which just delegates to the object it contains (as do all its methods).

Copyright (c) Marimer LLC