我不确定这是否有助于您的任务,但我最近学到并牢记的一件事是让您的数据模型的唯一标识符实现不直接传播到数据层之外,而是包装在抽象中。例如,这是一个包装模型标识符的接口:
public interface IModelIdentifier<T> where T : class
{
/// <summary>
/// A string representation of the domain the model originated from.
/// </summary>
string Origin { get; }
/// <summary>
/// The model instance identifier for the model object that this
/// <see cref="IModelIdentifier{T}"/> refers to. Typically, this
/// is a database key, file name, or some other unique identifier.
/// <typeparam name="KeyDataType">The expected data type of the
/// identifier.</typeparam>
/// </summary>
KeyDataType GetKey<KeyDataType>();
/// <summary>
/// Performs an equality check on the two model identifiers and
/// returns <c>true</c> if they are equal; otherwise <c>false</c>
/// is returned. All implementations must also override the equal operator.
/// </summary>
/// <param name="obj">The identifier to compare against.</param>
/// <returns><c>true</c> if the identifiers are equal; otherwise
/// <c>false</c> is returned.</returns>
bool Equals(IModelIdentifier<T> obj);
}
您的业务逻辑层过去可能将int
s 作为唯一标识符传递(例如,来自数据库表中的标识列),现在这样传递:
public IPerson RetrievePerson(IModelIdentifier<IPerson> personId)
{
/// Retrieval logic here...
}
然后,您的数据层将有一个类,IModelIdentifier<Person>
该类使用物理模型的唯一标识符实现并填充其内部数据类型。这将您的业务层与您在数据层可能进行的任何更改隔离开来,例如int
用 s 替换您的密钥标识符Guid
。