سؤال

هل هناك أي مشكلة محتملة في تعيين 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، الخ)، والتي سوف تحتاج إلى استخدام "مصنع".

وقال إن المصنع ننظر بشيء من هذا القبيل:

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
    }
  }
} 

"كيف للوصول إلى IRepository؟" قد تسأل؟

والخدمات طبقة الخاصة بك أن تفعل شيئا مثل:

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();

}

وأو كنت حقنه منشئ خدمة باستخدام نكهة المفضلة لديك عكس من حاوية تحكم مثل ذلك:

public class OrderService
{
  private IRepository _repo;

  public OrderService(IRepository repo)
  {
    _repo = repo;
  }

  public void GetNewOrdersForServices()
  {
    IList myList = _repo.GetNewOrders();

  }

إذا كنت لا fimilar مع المفاهيم محدد الخدمة، تحقق من قلعة وندسور لأنها تلخص فقط حول جميع احتياجاتك.

نصائح أخرى

مما قرأته، باستخدام DataContext "لأكثر من محادثة عمل واحدة عادة ما يكون الشيء الخطأ الذي يجب القيام به". قم بالتمرير لأسفل إلى لماذا هذا مهم؟ قسم للاقتباس.بسبب التخزين المؤقت وعوامل أخرى، يجب أن تعتبر DataContext الخاص بك قديمًا على الفور.من ذلك، من الآمن أن تقول أنك لا تريد الاحتفاظ بـ DataContext كخاصية يمكن إعادة استخدامها بكل طرقك.باستخدام اقتراح إريك دنكان، سوف تحتاج إلى تمرير نوع ما من مصنع DataContext للحصول على سياق جديد لكل استعلام.

لمناقشة تركز على DataContext، APress برو لينك الكتاب لديه الفصل بأكمله في DataContext، الصفحة الأخيرة جدا والذي ينصحك أيضًا "باعتبار DataContext قديمًا على الفور."

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top