Відображення на основі метаданих (шаблон проєктування)Відображення на основі метаданих (англ. Metadata Mapping) — шаблон проєктування, який пропонує не писати логіку відображення, а описати її метаданими. ОписУ більшості випадків код відображення даних із сховища у домені об'єкти виходить одноманітним та самоповторним. Даний шаблон пропонує описати правила відображення, які будуть загальними для всіх об'єктів. РеалізаціяІснує два основні підходи до реалізації цього шаблону: генерація коду і рефлексія. При використанні генерації коду, розробник пише програму, яка приймає метадані та створює класи відображення. Дані класи нічим не відрізняються від написаних вручну. З іншого боку рефлексія знаходить описані поля і співвідносить їх із колонками таблиці. Нехай дана таблиця у сховищі. public class PlayerTable
{
public ind id { get; set; }
public string name { get; set; }
}
Та об'єкт який описую цю таблицю. public class Player
{
public int Id { get; set; }
public string Name { get; set; }
}
Тоді опишемо загальний код відображення. class DataMap
{
private class ColumnMap
{
public string FieldName { get; set; }
public string ColumnName { get; set; }
}
private Type _domainClass;
private string _tableName;
private ICollection<ColumnMap> _columnMetedatas = new List<ColumnMap>();
public DataMap(Type domainClass, string tableName)
{
_domainClass = domainClass;
_tableName = tableName;
}
public void AddMetadata(string fieldName, string columnName)
{
_columnMetedatas.Add(new ColumnMap
{
FieldName = fieldName,
ColumnName = columnName,
});
}
public string GetTableName()
{
return _tableName;
}
public IEnumerable<string> GetColumns()
{
return columnMetedatas.Select(c => c.ColumnName);
}
public object GetDomainObject(object record)
{
// використання рефлексії
var domainObject = Activator.CreateInstance(_domainClass);
foreach(var metadate in _columnMetedatas)
{
var tableColumnData = record.Read(metadate.ColumnName);
var propertyInfo = _domainClass.GetProperty(metadate.FieldName);
propertyInfo.SetValue(domainObject, tableColumnData);
}
return domainObject;
}
}
Конкретний клас відображення матиме наступний вигляд: class PlayerMapper
{
private DataMap _dataMap;
public PlayerMapper()
{
_dataMap = new DataMap(typeof(Player), "PlayerTable");
_dataMap.AddMetadata("Id", "id");
_dataMap.AddMetadata("Name", "name");
}
public Player findObject (int id) {
var sql = $@"
SELECT {string.Join(" , ", _dataMap.GetColumns())}
FROM {_dataMap.GetTableName()}
WHERE id = {id}";
var record = db.Execute(sql);
return _dataMap.GetDomainObject(record) as Player;
}
. . .
}
Див. такожДжерела
|