これがあなたの探求に役立つかどうかはわかりませんが、私が最近学んだことの 1 つは、データ モデルの一意の識別子の実装をデータ レイヤーの外部に直接伝達するのではなく、抽象化でラップすることです。たとえば、モデルの識別子をラップするインターフェイスは次のとおりです。
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 を一意の識別子として (たとえば、データベース テーブルの ID 列から)渡していた可能性があるビジネス ロジック レイヤーは、次のように渡されます。
public IPerson RetrievePerson(IModelIdentifier<IPerson> personId)
{
/// Retrieval logic here...
}
データ層にはIModelIdentifier<Person>
、物理モデルの一意の識別子を使用して内部データ型を実装および設定するクラスがあります。int
これにより、キー識別子をGuid
sに置き換えるなど、データ層で行う可能性のある変更からビジネス層を隔離します。