データアクセス層に次のクラス構造があるとします。
interface IBehavior<in T>
{
void Load(T model);
}
class ModelManager<T>
{
ModelManager(IEnumerable<IBehavior<T>> behaviors) { ... }
void Load(T model)
{
foreach (var behavior in behaviors) {
behavior.Load(model)
}
}
}
これにより、モデルで実装できるさまざまなインターフェイスと、それらのインターフェイスを処理する再利用可能な動作を使用できます。
interface IUnique { ... }
class UniqueBehavior : IBehavior<IUnique> { ... }
interface ITimestampable { ... }
class TimestampableBehavior : IBehavior<ITimestampable> { ... }
そして、マネージャーは、の共変性のためにこれらを喜んで受け取りますIBehavior<T>
。
class MyModel : IUnique, ITimestampable { ... }
new ModelManager<MyModel>(new IBehavior<MyModel>[] {
new UniqueBehavior(),
new TimestampableBehavior()
});
素晴らしい。
しかし、ここで、各動作に一連のLINQフィルターをエンティティにも適用させたいと思います。私の最初のアイデアは、このメソッドをIBehavior<T>
次のように追加することでした。
void ApplyFilters<IEnumerable>(ref IEnumerable<T> models)
...実装動作はWhere
、その裁量で列挙に一連の句を適用します。
ただし、結局のところ、refパラメーターでは型のバリエーションは許可されていません。型の安全性とインターフェースの反変の性質の両方を維持しながら、この種の機能を実装する方法を見つけるのに苦労しています。どんなアイデアでも大歓迎です。