Datacontextをリポジトリのプロパティとして設定しても大丈夫ですか?
-
03-07-2019 - |
質問
次のようにdatacontextをプロパティとして設定する際に潜在的な問題があります:
リポジトリ
public Repository()
{
public DataContext dc {get;set;}
public GetOrders(int id)
{ ...from dc.Orders...}
}
サービス層:
public GetNewOrders()
{
....
Repository rep=new Repository();
using {DataContext dc=new DataContext())
{
rep.dc=dc;
rep.GetOrders(id);
}
}
解決
DDDでは、具体的なクラスを参照することにより、ここで全体像を把握できません。リポジトリと「サービスレイヤー」の間のインターフェースではありません。ベストプラクティスによる。リポジトリにDataContextを注入する必要がある場合は、次のようにリファクタリングすることをお勧めします。
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(IDataContext dataContext)
{
_dataContext = dataContext;
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
より良い解決策は、リポジトリがDataContextを単独で処理できるようにすることです-基礎となる要件をマスクすることにより、コンサートの分離を有効に保ちます:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(String connectionString)
{
_dataContext = new DataContext(connectionString);
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
自分でDataContext(または別のクラス)の制御を維持する必要がある場合(おそらく、静的参照を保持したり、WebRequestに基づいて設定を変更したい場合など)、&quot; Factory&quot;を使用する必要があります。 。
ファクトリは次のようになります。
public static class DataContextFactory
{
public static IDataContext GetInstance()
{
// return either a static instance,
// or threaded instance, a GlobalContext instance
// or whatever your preference is here
//
}
}
このようにして、DataContextのインスタンスを「サービス」外で制御する方法を完全に制御できます。層。したがって、このDataContextFactoryは次のように使用します。
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
public IList<Orders> GetNewOrders()
{
using (var dataContext = DataContextFactory.GetInstance())
{
// dataContext is now your IDataContext to work with
}
}
}
&quot; IRepositoryへのアクセス方法&quot;質問してもいいですか?
サービスレイヤーは次のようになります。
public void GetNewOrdersForServices()
{
// Not recommended!
// IRepository repo = new Repository()
//
// The following is recommended instead; because, it removes the
// the Concret reference from your Services layer completely!
//
IRepository repo = ServiceLocator.InstanceOf<IRepository>();
IList myList = repo.GetNewOrders();
}
または、Inversion of Controlコンテナーの好みのフレーバーを使用して、サービスのコンストラクターに挿入します。
public class OrderService
{
private IRepository _repo;
public OrderService(IRepository repo)
{
_repo = repo;
}
public void GetNewOrdersForServices()
{
IList myList = _repo.GetNewOrders();
}
サービスロケーターの概念に慣れていない場合は、Castle Windsorをチェックしてください。これにより、ほぼすべてのニーズがカプセル化されます。
他のヒント
DataContext&quot; を使用して読んだものから複数のビジネス会話が通常、間違っていること です。&quot;引用の[これが重要な理由]セクションまでスクロールします。キャッシュおよびその他の要因により、DataContextの失効をすぐに考慮する必要があります。このことから、すべてのメソッドで再利用されるプロパティとしてDataContextを保持したくないと言っても安全です。 Eric Duncanの提案を使用して、ある種のDataContextファクトリーを渡して、各クエリの新しいコンテキストを取得します。
DataContextに焦点を当てた議論のために、APress Pro LINQ ブックには非常に最後のページでは、「DataContextの失効を直ちに検討する」ことも推奨されています。