在大量阅读有关存储库和数据映射器的内容后,我决定在测试项目中实现这些模式。由于我对这些不熟悉,我想了解您对我如何在一个简单的项目中实现这些的看法。
杰里米·米勒 说:
做一些不平凡的个人编码项目,您可以在其中自由地尝试设计模式。
但我不知道我做的这一切是否正确。
这是我的项目结构:
正如您所看到的,有很多文件夹,我将在下面详细描述它们。
-
域:项目域实体放在这里我有一个简单的 Personnel 类,它继承自 EntityBase 类,EntityBase 类有一个名为 Id 的属性。
public int Id { get; set; }
-
基础设施:这是一个包含两个类的简单数据访问层。 SqlDataLayer 是一个简单的类,它继承自名为DataLayer 的抽象类。在这里我提供了一些功能,例如以下代码:
public SQLDataLayer() {
const string connString = "ConnectionString goes here";
_connection = new SqlConnection(connString);
_command = _connection.CreateCommand();
}
将参数添加到命令参数集合:
public override void AddParameter(string key, string value) {
var parameter = _command.CreateParameter();
parameter.Value = value;
parameter.ParameterName = key;
_command.Parameters.Add(parameter);
}
执行 DataReader :
public override IDataReader ExecuteReader() {
if (_connection.State == ConnectionState.Closed)
_connection.Open();
return _command.ExecuteReader();
}
等等。
- 存储库:这里我尝试实现存储库模式。 IRepository 是一个通用接口
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);
}
存储库.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;
}
我没有公开 IRepository 中未实现的方法。
在 Generic Repository 类中,我期望构造函数中有两个参数,第一个是对 SqlDataLayer 类的引用,第二个是对 Entity DataMapper 的引用。
这些参数由继承自 Repository 类的每个 Entities Repository 类发送。例如 :
public class PersonnelRepository : Repository<Personnel>, IPersonnelRepository {
public PersonnelRepository(DataLayer domainContext, PersonnelDataMapper dataMapper)
: base(domainContext, dataMapper) {
}
}
正如您在 FindOne 方法中看到的,我尝试自动化一些操作,例如创建 CommandText,然后我利用 DataLayer 类来配置命令,最后执行命令来获取 IDataReader。我将 IDataReader 传递给 DataMapper 类以映射到实体。
-
DomainMapper:最后,我将 IDataReader 的结果映射到实体,下面是如何映射人员实体的示例:
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);
}
我知道我在这里犯了很多错误,这就是我来这里的原因。我需要您的建议来了解我做错了什么或者这个简单的测试项目有哪些优点。
提前致谢。