After a lots of read about Repository and Data Mapper I decided to implement those patterns in a test project. Since I'm new to these I'd like to get your views about how did I implement those in a simple project.
Jeremy Miller says :
Do some sort of nontrivial, personal coding project where you can freely experiment with design patterns.
But I don't know I did all this things right or not.
Here is my project structure :

As you can see there are many folders which I'm going to describe them in detail in below.
- Domain : Project Domain Entities go here I've a simple Personnel class which is inherited from EntityBase class, EntityBase class has a single property named Id. - public int Id { get; set; }
- Infrustructure : Here is a simple Data Access Layer with two classes. SqlDataLayer is a simple class which is inherited from an abstract class named DataLayer. Here I provide some functionality like following code : - public SQLDataLayer() { const string connString = "ConnectionString goes here"; _connection = new SqlConnection(connString); _command = _connection.CreateCommand(); }
adding parameter to commands parameter collection :
    public override void AddParameter(string key, string value) {
        var parameter = _command.CreateParameter();
        parameter.Value = value;
        parameter.ParameterName = key;
        _command.Parameters.Add(parameter);
    }
executing DataReader :
    public override IDataReader ExecuteReader() {
        if (_connection.State == ConnectionState.Closed)
            _connection.Open();
        return _command.ExecuteReader();
    }
and so on.
- Repository : Here I tried to implement repository pattern. IRepository is a generic interface
IRepository.cs :
public interface IRepository<TEntity> where TEntity : EntityBase
{
    DataLayer Context { get; }
    TEntity FindOne(int id);
    ICollection<TEntity> FindAll();
    void Delete(TEntity entity);
    void Insert(TEntity entity);
    void Update(TEntity entity);
}
Repository.cs :
public class Repository<TEntity> : IRepository<TEntity> where TEntity : EntityBase, new() {
    private readonly DataLayer _domainContext;
    private readonly DataMapper<TEntity> _dataMapper;
    public Repository(DataLayer domainContext, DataMapper<TEntity> dataMapper) {
        _domainContext = domainContext;
        _dataMapper = dataMapper;
    }
    public DataLayer Context {
        get { return _domainContext; }
    }
    public TEntity FindOne(int id)
    {
        var commandText = AutoCommand.CommandTextBuilder<TEntity>(CommandType.StoredProcedure, MethodType.FindOne);
        // Initialize parameter and their types
        Context.AddParameter("Id", id.ToString(CultureInfo.InvariantCulture));
        Context.SetCommandType(CommandType.StoredProcedure);
        Context.SetCommandText(commandText);
        var dbReader = Context.ExecuteReader();
        return dbReader.Read() ? _dataMapper.Map(dbReader) : null;
    }
I didn't expose not implemented methods from IRepository.
Here in Generic Repository class I expect two parameters in constructor first is a reference to my SqlDataLayer class and second is a reference to Entity DataMapper. Those parameters sent by each Entities Repository class which inherited from Repository class. for example :
public class PersonnelRepository : Repository<Personnel>, IPersonnelRepository {
    public PersonnelRepository(DataLayer domainContext, PersonnelDataMapper dataMapper)
        : base(domainContext, dataMapper) {
    }
}
As you can see here in the FindOne method I tried to automate some operation such as creating CommandText, then I took the advantage of my DataLayer class to configure command and finally execute command to get IDataReader. I pass IDataReader to my DataMapper class to map to the Entity.
- DomainMapper : Finally here I map result of IDataReader to Entities, bellow is a sample of how I map Personnel entity : - public class PersonnelDataMapper : DataMapper<Personnel> { public override Personnel Map(IDataRecord record) { return new Personnel { FirstName = record["FirstName"].ToString(), LastName = record["LastName"].ToString(), Address = record["Address"].ToString(), Id = Convert.ToInt32(record["Id"]) }; }}
Usage :
    using (var context = new SQLDataLayer()) {
        _personnelRepository = new PersonnelRepository(context, new PersonnelDataMapper());
            var personnel  = _personnelRepository.FindOne(1);
    }
I know I did many mistake here, that's why I'm here. I need your advice to know what I did wrong or what are the good points in this simple test project.
Thanks in advance.
 
     
    