私はデータアクセス層を緩く結合して遊んでいます。依存性注入プロセスは非常に役立ちましたが、ジェネリックスの使用を検討する際に少し難問に遭遇しました。
ジェネリック型パラメーターをサポートするクラスを取得して、真に分離され、型に対して安全にする方法はありますか?私の懸念は、共通のインターフェイスに書き込んだとしても、派生した型が最初にコーディングしたエンティティと異なる場合、コンパイラがキャッチできない厄介なランタイムエラーが発生する可能性があることです。
問題は、データベースからデータを取得してオブジェクトをハイドレイトするコードを作成するときに、次のレイヤーに実装しようとすると難問に直面することです。以下のFoo2などのクラスを渡すと、「暗黙の」変換がないため、コードを壊す可能性があります。私はリフレクションを使って物事を緩めようとしていましたが、データベースからデータを取得するときに具体的なタイプをハイドレイトする必要があるという問題に戻ってきます。そのタイプは、キャストとタイプ保証に関する問題を引き起こします。さらに、エンティティライブラリ内の多くのタイプすべてのすべてのメソッドを抽象化する場合は、リフレクションを使用してこれを行うことができますが、ジェネリックは明示的に「where T:ISomeInterface」ステートメントでのみタイプ保証を行うことができるという問題が発生します。 。ついに、このモデルは、今後さらに派生型が存在する場合、またはインターフェイスから分岐して新しい型を形成する型がある場合に機能しなくなります。これまでに作成されたすべてのタイプに新しいデータアクセスオブジェクトを実装する必要があると考えると、データアクセス層に変更が強制されます。それは私の心の中の緩い結合の定義を破ります。
これらすべてが私を疑問に戻させているようです-ジェネリックは本当に緩い結合の方法で使用できますか?もしそうなら、あなたはどのような参考文献を提供できますか?
簡略化した例:
public interface IEntity
{
// stuff for state and methods ...
}
public interface IRepository<T> where T : IEntity
{
void Save(out int id, T obj);
T Load(int id);
}
public interface IFoo : IEntity
{
int Id { get; set; }
//All other IEntities goodness
//Some new goodness specific to Foo
}
//Concrete Entities:
public class Foo : IFoo
{
// blah blah
}
public class Foo2 : IFoo
{
// new blah blah
}
public class FooRepository : IRepository<Foo> //OOPS, Looks like we have settled in on a concrete type!
{
public void Save(out int id, Foo obj)
{
// ADO.NET code to access Sql ...
id = 1;// this would actually be the result of the Sql insert output parameter
return;
}
public Foo Load(int id)
{
Foo foo = new Foo();
// ADO.Net code to access Sql
return foo;
}
}
では、IFoo派生オブジェクトを処理でき、プログラマーが将来何をするかに関係なく、完全に形成された具象型を返すことができるコードをどのように処理しますか?ジェネリック部分を捨てて、依存性注入に固執するのが最善ですか?どんな参考文献、ガイダンスなども素晴らしいでしょう。