単純なPOCOを目的とした単純なクラスがあります。データを保持するだけです。1つの例外を除いて:メモのコレクションが含まれています。このコレクションを遅延ロードして、それらを必要としないページ上のメモをフェッチする必要がないようにします。このためのスタブはこれです:
public class MyDTOClass
{
private ICollection<Note> _notes = null;
public ICollection<Note> Notes
{
get
{
if(_notes == null)
{
// Get an INoteRepository and initialize the collection
}
return _notes;
}
}
}
さて、ここからどうやって進めたらいいのかしら。これはASP.netMVCアプリケーションであり、依存性注入を使用して、IRepositoriesを必要とするクラス(コントローラーなど)に注入します。ただし、このクラスは非常に単純なDTOであると想定されているため、INoteRepositoryを挿入することには消極的です。これは、呼び出し元が遅延読み込みであるという事実を心配したり気にしたりする必要がないためです。
そのため、INoteRepositoryを保持する別のクラスをモデルに含めることを考えています。
public class MyDataAccessClass
{
private INoteRepository _noteRepo;
// Inject is part of Ninject and makes sure I pass the correct
// INoteRepository automatically
[Inject]
public MyDataAccessClass(INoteRepository noteRepository)
{
_noteRepo = noteRepository;
}
public IEnumerable<Note> GetNotes(int projectId)
{
return _noteRepo.GetNotes(projectId);
}
}
これはもちろん機能しますが、これが正しいアーキテクチャであるかどうか疑問に思います。単純なDTOClassを別のデータアクセスクラスに結合し、場合によってはDIメカニズムにも結合します(Notesのゲッターでデータアクセスクラスのインスタンスを作成する必要があるため)。
別の方法でやりますか?私がすでにNinjectを使用していることを念頭に置いて、これを行うためのより良い方法はありますか?
ロジックが含まれているため、これはPOCOまたはDTOではなくなったと思いますが、問題ありません。外部の呼び出し元にはPOCOのように見せたいので、このクラスや他のクラスに「GetNotesForProject」のようなメソッドではなく、プロパティ「Notes」を設定したいと思います。
私の現在のソリューションは本当に醜いです。MvcApplicationからNinjectカーネルを取得し、それを使用してコンストラクターでINoteRepositoryを取得するProjectDataProviderクラスを起動し、INoteRepositoryを「DTO」クラスのどこかに配置する必要がないようにする必要があります。 :
public ICollection<Note> Notes
{
get
{
if(_notes == null)
{
var app = HttpContext.Current.ApplicationInstance as MvcApplication;
if (app == null)
throw new InvalidOperationException("Application couldn't be found");
var pdp = app.Kernel.Get<ProjectDataProvider>();
_notes = new List<Note>(pdp.GetNotes(Id));
}
return _notes;
}
}
編集:報奨金を開きました。「POCO」と「DTO」の用語は無視して、それに応じてリファクタリングします。つまり、これは次のことです。このような状況で遅延読み込みコードはどのように見えるべきでしょうか。また、INoteRepositoryをMyDTOClassに渡さないようにすることはできますか。