I have the following situation:
I have...
Models
likeServerRoom
andServerCabinet
Repositories
of theModel
instances (in-memory collection)PersistenceServices
which are interfacing the persistence-method I chose (mssql db)
The problem I am facing is repetition.
Basically, the implementation of a PersistenceService
is not really bound to a specific Model
, only to it's instantiation
(from a DataRow
) and conversion (from Business Object to DataRow
), so I thought the following would be good:
From
/// <summary>
/// Implements generic database-crud operations to prevent repetition
/// Most of the CRUD-operations are the exactly the same, and those are implemented
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class DbPersistenceService<T> : IPersistenceService<T>
where T : class
{
protected DataTable _dataTable;
// Update, Delete, GetAll, Save, Delete, Contains and FindRow excluded
/// <summary>
/// Add an instance to the repository
/// </summary>
/// <param name="instance"></param>
public void Add(T instance)
{
_dataTable.Rows.Add(ObjectToRow(instance));
}
/// <summary>
/// Get the instance with the specified id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public T GetById(long id)
{
var row = FindRow(id);
if (row == null)
return null;
return RowToObject(FindRow(id));
}
/// <summary>
/// Converts a datarow to the domain object
/// </summary>
/// <param name="row"></param>
/// <returns></returns>
protected abstract T RowToObject(DataRow row);
/// <summary>
/// Converts a domain object to a datarow
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
protected abstract DataRow ObjectToRow(T instance);
}
So, the CRUD operations are the same for each model, only the conversion between domain and persistence layer is different (constructor of ServerCabinet
needs other information from a DataRow
than a ServerRoom
) and this conversion is must be implemented by overriding RowToObject
and ObjectToRow
.
I am not satisfied with this design, as I still have to maintain one PersistenceService
-class for each Model
(e.g. ServerCabinetDbPersistenceService
). I tried things like an interface IBusinessDataConverter
, but it doesnt work, because that would be instance-methods whereas methods like GetById
(above) cannot access an instance, only static, class-level methods.
How would you design it, do you have other general info about bad-practices I used?
/* Using an ORM like EntityFramework is not an option */