आज सुबह मेरे कंप्यूटर को बूट करना मुझे उस परियोजना के लिए सही समस्या का सामना करना पड़ा जिस पर मैं काम कर रहा हूं। मेरे पास कुछ विचार थे जो निम्नलिखित डिज़ाइन का नेतृत्व करते हैं - और टिप्पणियां कमाल से अधिक होंगी। दुर्भाग्यवश जोश द्वारा सुझाए गए डिज़ाइन संभव नहीं हैं, क्योंकि मुझे रिमोट एसक्यूएल सर्वर के साथ काम करना है और यह वितरित लेनदेन समन्वयक सेवा को सक्षम नहीं कर सकता है।
मेरा समाधान मेरे मौजूदा कोड में कुछ सरल परिवर्तनों पर आधारित है।
सबसे पहले, मैं अपने सभी खजाने एक सरल मार्कर इंटरफ़ेस को लागू है:
/// <summary>
/// Provides methods to enable transaction support.
/// </summary>
public interface IHasTransactions : IRepository
{
/// <summary>
/// Initiates a transaction scope.
/// </summary>
void BeginTransaction();
/// <summary>
/// Executes the transaction.
/// </summary>
void CommitTransaction();
}
विचार में है जो:
/// <summary>
/// A base interface for all repositories to implement.
/// </summary>
public interface IRepository
{ }
दूसरे, मैं अपने सभी लेनदेन सक्षम खजाने निम्नलिखित इंटरफ़ेस को लागू करते हैं मेरे सभी रिपॉजिटरीज मैं इस इंटरफ़ेस को कार्यान्वित करता हूं और कोड जोड़ता हूं जो वास्तविक प्रदाता के आधार पर सीधे लेनदेन पेश करता है (नकली भंडारों के लिए मैंने प्रतिनिधियों की एक सूची बनाई है जो प्रतिबद्धता पर निष्पादित हो जाती है)। LINQ SQL करने के लिए यह इस तरह के रूप कार्यान्वयन सुनिश्चित करने के लिए आसान होगा:
#region IHasTransactions Members
public void BeginTransaction()
{
_db.Transaction = _db.Connection.BeginTransaction();
}
public void CommitTransaction()
{
_db.Transaction.Commit();
}
#endregion
निश्चित रूप से
यह जरूरी है कि एक नया भंडार वर्ग प्रत्येक थ्रेड के लिए बनाई गई है, लेकिन यह मेरा परियोजना के लिए उचित है।
रिपोजिटरी का उपयोग करने वाली प्रत्येक विधि को BeginTransaction()
और EndTransaction()
का आह्वान करने की आवश्यकता है, यदि भंडार IHasTransactions
लागू करता है। इस कॉल को और भी आसान बनाने के लिए, मैं निम्नलिखित एक्सटेंशन के साथ आया:
/// <summary>
/// Extensions for spawning and subsequently executing a transaction.
/// </summary>
public static class TransactionExtensions
{
/// <summary>
/// Begins a transaction if the repository implements <see cref="IHasTransactions"/>.
/// </summary>
/// <param name="repository"></param>
public static void BeginTransaction(this IRepository repository)
{
var transactionSupport = repository as IHasTransactions;
if (transactionSupport != null)
{
transactionSupport.BeginTransaction();
}
}
public static void CommitTransaction(this IRepository repository)
{
var transactionSupport = repository as IHasTransactions;
if (transactionSupport != null)
{
transactionSupport.CommitTransaction();
}
}
}
टिप्पणियों की सराहना की जाती है!
स्रोत
2009-02-23 11:51:36
मुझे नहीं लगता कि यह डीडीडी की भावना में एक समाधान है। असल में आपने एक लेनदेन लिपि बनाई है जो डोमेन मॉडल का काम करता है। सेवा को ग्राहक की स्थिति में बदलाव नहीं करना चाहिए, उदाहरण के लिए। –
कोड में कुछ इस व्यवसाय नियम को संभालना है, इसे इस स्तर पर या उच्च स्तर पर एक बिंदु एक लेनदेनस्कोप के भीतर परिवर्तन कर रहा था या तो स्थानीय लेनदेन या लेनदेन को संभालने के लिए वितरित लेनदेन की अनुमति देता है।यदि व्यवसाय नियम कहता है कि जब भी ऑर्डर दिया जाता है तो ग्राहक को अपडेट करें, तो यह ऑर्डर करने के लिए एक अच्छी जगह है क्योंकि सभी ऑर्डर यहां से गुजरते हैं। – JoshBerke