Menggunakan DynamicObject
Seperti halnya menggunakan class ExpandoObject, melalui class DynamicObject kita dapat mengubah behavior dari sebuah objek secara runtime, serta melakukan override default behavior dari object tersebut, misalnya overriding terhadap method, property, atau type conversion.
Pada contoh berikut, kita akan mengubah behavior dari sebuah class DataRow sehingga pembuatan DataColumn dalam DataRow tersebut dapat dilakukan secara runtime.
Misalkan pada contoh code berikut:
DataTable table = new DataTable();
DataRow row = table.NewRow();
row[“Name”] = “Paul”;
Jika code di atas dijalankan maka akan terjadi exception dengan pesan “Column ‘Name’ doest belong to table”.
Berikut ini kita akan membuat sebuah class baru yang behaviornya menyerupai class DataRow, namun di-inherit dari DynamicObject.
using System;
using System.Data;
using System.Dynamic;
public class DynamicDataRow : DynamicObject
{
private DataRow dataRow = null;
private DataTable dataTable = null;
public DynamicDataRow(DataTable dataTable)
{
dataRow = dataTable.NewRow();
this.dataTable = dataTable;
}
public DataRow GetDataRow()
{
return dataRow;
}
public override bool TryGetMember(
GetMemberBinder binder,
out object result)
{
if (dataRow.Table.Columns.Contains(binder.Name))
{
result = dataRow[binder.Name];
return true;
}
result = null;
return false;
}
public override bool TrySetMember(
System.Dynamic.SetMemberBinder binder,
object value)
{
if (!dataRow.Table.Columns.Contains(binder.Name))
{
dataRow.Table.Columns.Add(binder.Name, value.GetType());
}
dataRow[binder.Name] = value;
if (dataTable.Rows.IndexOf(dataRow) < 0)
{
dataTable.Rows.Add(dataRow);
}
return true;
}
}
dengan demikian kita bisa menggunakan class di atas seperti berikut ini
DataTable table = new DataTable();
dynamic row1 = new DynamicDataRow(table);
row1.Name = "Paul";
row1.City = "Jakarta";
row1.Age = 30;
row1.Active = true;
dynamic row2 = new DynamicDataRow(table);
row2.Name = "John";
row2.City = "London";
row2.Age = 50;
dynamic row3 = new DynamicDataRow(table);
row3.Name = "Jack";
row3.City = "Jakarta";
row3.Age = 28;
Perhatikan pada code di atas, sebuah DataRow dapat ditambahkan ke dalam object table (instance dari DataTable), tanpa melalui method table.Rows.Add(), karena pemanggilan method tersebut sudah kita lakukan dalam method TrySetMember.
Namun, jika kita ingin mengakses sebuah property di class DataRow, masih tidak dapat dilakukan, misalnya property ItemArray dari class DataRow. Pada method TryGetMember harus dilakukan pengubahan sebagai berikut:
public override bool TryGetMember(
System.Dynamic.GetMemberBinder binder,
out object result)
{
if (dataRow.Table.Columns.Contains(binder.Name))
{
result = dataRow[binder.Name];
return true;
}
else
{
Type dataRowType = dataRow.GetType();
result = dataRowType.InvokeMember(
binder.Name,
BindingFlags.GetProperty |
BindingFlags.Public |
BindingFlags.Instance,
null, dataRow, null);
return true;
}
result = null;
return false;
}
}
Jangan lupa untuk menambahkan
using System.Reflection;
Untuk lebih jelasnya, dapat mendownload attachment dari postingan ini.