This is a update on Fluent Interface patter based on my previous blog. The update is based on a much simplified interface for generic domain object.
First, I defined the following interface:
public interface IDomainObjReaderFluent<T> where T: class
{
IDomainObjFluent ReadData(int byIndex);
IDomainObjFluent ReadData(string byName);
T GetObject();
}
The interface defines two ways to read data, by index or by name. For the example of Employee class, the implementation class is:
class EmployeeReaderFluent : IDomainObjReaderFluent
{
private IDbReader _reader;
private int _id;
private string _name;
private DateTime _dob;
//...
public EmployeeReaderFluent<Employee>(IDbReader reader)
{
_id = 0;
_name = null;
_bod = DateTime.Now;
_reader = reader;
}
IDomainObjReaderFluent ReadData(int byIndex)
{
if ( byIndex == EmployeeConst.IdIndex )
{ _id = _reader.GetInt32(byIndex); }
else if ( byIndex == EmployeeConst.NameIndex )
{ _name = _reader.GetString(byIndex); }
else if ( byIndex == EmployeeConst.BODIndex )
{ _bod = _reader.GetDateTime(byIndex); }
//...
}
// ReadData(string byName) skipped ...
Employee GetObject() {
return new Employee(_id, _name, _dob, ...);
}
}
In the implementation of the interface for a domain object, the class has complete knowledge of how each field is retrieved from IDbReader or a data reader. In other words, it will be up to the implementation class to decide how to get data from the data reader. The data reader instance can be passed in through its CTOR.
Here is an example of its usage:
Employee empl = new
EmployeeReaderFluent<Employee>(myDbReader).
ReadData(EmployeeConst.IdIndex).
ReadData(EmployeeConst.NameIndex).
ReadData(EmployeeConst.BodIndex).
...
GetObject();
where myDbReader is an instance of IDbReader, and EmployeeConst is a class with only constants of index values for each field. I prefer to use const class to embedded literal constants.