-
Notifications
You must be signed in to change notification settings - Fork 113
Reflection.ObjectFactory
Igor Tkachev edited this page May 20, 2016
·
1 revision
The following example shows how to create objects of different types coming from the same data source.
Typically, to create an object, BLToolkit calls the TypeAccessor.CreateInstanceEx method. First of all, this method verifies if there is an object factory (ObjectFactory property) associated with the creating object’s type. If the property value is not null, it is used to create an object.
The ObjectFactory property can be assigned explicitly at any time or by decorating the target class with the ObjectFactory attribute.
ObjectFactory.cs
using System;
using System.Collections.Generic;
using NUnit.Framework;
using BLToolkit.Data;
using BLToolkit.Mapping;
using BLToolkit.Reflection;
namespace HowTo.Reflection
{
[TestFixture]
public class ObjectFactoryTest
{
[ObjectFactory(typeof(Person.ObjectFactory))]
public class Person
{
[MapField("PersonID")]
public int ID;
public string LastName;
public string FirstName;
public string MiddleName;
class ObjectFactory : IObjectFactory
{
public object CreateInstance(TypeAccessor typeAccessor, InitContext context)
{
// Get the object type indicator field.
//
object objectType = context.DataSource.GetValue(context.SourceObject, "PersonType");
// Target ObjectMapper must be changed in order to provide correct mapping.
//
switch ((string)objectType)
{
case "D": context.ObjectMapper = ObjectMapper<Doctor>. Instance; break;
case "P": context.ObjectMapper = ObjectMapper<Patient>.Instance; break;
}
// Create an object instance.
// Do not call ObjectMapper.CreateInstance as it will lead to infinite recursion.
//
return context.ObjectMapper.TypeAccessor.CreateInstance(context);
}
}
}
public class Doctor : Person
{
public string Taxonomy;
}
public class Patient : Person
{
public string Diagnosis;
}
[Test]
public void Test()
{
using (DbManager db = new DbManager())
{
List<Person> list = db
.SetCommand(@"
SELECT
ps.*,
d.Taxonomy,
p.Diagnosis,
CASE
WHEN d.PersonID IS NOT NULL THEN 'D'
WHEN p.PersonID IS NOT NULL THEN 'P'
END as PersonType
FROM
Person ps
LEFT JOIN Doctor d ON d.PersonID = ps.PersonID
LEFT JOIN Patient p ON p.PersonID = ps.PersonID
ORDER BY
ps.PersonID")
.ExecuteList<Person>();
Assert.AreEqual(list[0].GetType(), typeof(Doctor));
Assert.AreEqual(list[1].GetType(), typeof(Patient));
if (list.Count > 2)
Assert.AreEqual(list[2].GetType(), typeof(Person));
}
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add
name = "DemoConnection"
connectionString = "Server=.;Database=BLToolkitData;Integrated Security=SSPI"
providerName = "System.Data.SqlClient" />
</connectionStrings>
</configuration>