Відображення на основі метаданих (шаблон проєктування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Відображення на основі метаданих (англ. 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;
	}
		. . .
}

Див. також[ред. | ред. код]

Джерела[ред. | ред. код]