मुझे खुद को एक कनेक्शन ऑब्जेक्ट को पास करने की आवश्यकता है, इसलिए मैं कई व्यावसायिक वस्तुओं को एक ही लेनदेन के भीतर डेटाबेस में सहेजने की अनुमति दे सकता हूं।
यदि प्रत्येक व्यवसाय ऑब्जेक्ट को डेटाबेस में अपना स्वयं का SQLConnection बनाना होता है, तो लेनदेन एक वितरित लेनदेन में बढ़ेगा और मैं इससे बचना चाहता था।
मुझे किसी ऑब्जेक्ट को सहेजने के लिए पैरामीटर के रूप में SQLConnection ऑब्जेक्ट को पास करना पसंद नहीं आया, इसलिए मैंने एक कनेक्शन मैनेजर बनाया जो SQLConnection ऑब्जेक्ट बनाने के लिए SQLConnection ऑब्जेक्ट बनाने, SQLConnection ऑब्जेक्ट के उपयोग को ट्रैक करने और SQLConnection ऑब्जेक्ट को डिस्कनेक्ट करने पर संभालता है बेकार।
यहाँ ConnectionManager का एक उदाहरण के रूप में कुछ कोड है:
public class ConnectionManager: IDisposable
{
private ConnectionManager instance;
[ThreadStatic]
private static object lockObject;
private static Object LockObject
{
get
{
if (lockObject == null)
lockObject = new object();
return lockObject;
}
}
[ThreadStatic]
private static Dictionary<string, ConnectionManager> managers;
private static Dictionary<string, ConnectionManager> Managers
{
get
{
if (managers == null)
managers = new Dictionary<string, ConnectionManager>();
return managers;
}
}
private SqlConnection connection = null;
private int referenceCount;
private string name;
public static ConnectionManager GetManager(string connectionName)
{
lock (LockObject)
{
ConnectionManager mgr;
if (Managers.ContainsKey(connectionName))
{
mgr = Managers[connectionName];
}
else
{
mgr = new ConnectionManager(connectionName);
Managers.Add(connectionName, mgr);
}
mgr.AddRef();
return mgr;
}
}
private ConnectionManager(string connectionName)
{
name = connectionName;
connection = new SqlConnection(GetConnectionString(connectionName));
connection.Open();
}
private string GetConnectionString(string connectionName)
{
string conString = Configuration.ConnectionString;
return conString;
}
public SqlConnection Connection
{
get { return connection; }
}
private void AddRef()
{
referenceCount += 1;
}
private void DeRef()
{
lock (LockObject)
{
referenceCount -= 1;
if (referenceCount == 0)
{
connection.Dispose();
Managers.Remove(name);
}
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
DeRef();
}
}
~ConnectionManager()
{
Dispose(false);
}
#endregion
}
यहाँ कैसे मैं एक व्यवसाय वस्तु से इसका इस्तेमाल होता है:
public void Save()
{
using (ConnectionManager mrg = ConnectionManager.GetManager("SQLConnectionString")
{
using (SQLCommand cmd = new SQLCommand)
{
cmd.connection = mgr.Connection
// More ADO Code Here
}
_childObject.Save(); //this child object follows the same pattern with a using ConnectionManager.
}
}
मैं एक व्यवसाय वस्तु और को सहेज अपने बच्चों को एक ही कनेक्शन ऑब्जेक्ट का उपयोग करके बचाया जाता है। जब दायरे मूल माता-पिता से दूर हो जाता है, तो उपयोग कथन कनेक्शन बंद कर देता है।
यह एक पैटर्न है जिसे मैंने रॉकी लोट्का से अपने सीएसएलए ढांचे में सीखा।
कीथ
स्रोत
2009-01-05 20:07:42
धन्यवाद कीथ। मुझे वास्तव में आपका दृष्टिकोण पसंद है - कनेक्शन मैनेजर कनेक्शन और कमांड के बीच एक अच्छी परत है (यदि आप वास्तव में चाहते हैं तो आप अपने स्वयं के पूलिंग को भी कार्यान्वित कर सकते हैं)। मुझे सीएसएलए से इस अध्याय को पढ़ना होगा। –
मैं उलझन में हूं कि आप प्रबंधकों के सदस्य को थ्रेडस्टैटिक क्यों चिह्नित करना चाहते हैं। जब भी गेटटर को नए थ्रेड से एक्सेस किया जाता है, तो उस थ्रेड के लिए एक नया प्रबंधक संग्रह बनाया जाएगा? – dnewcome
मैं देखता हूं कि आप थ्रेड सुरक्षा दृष्टिकोण से प्रत्येक धागे के लिए अलग प्रबंधकों को क्यों चाहते हैं। आप नहीं चाहते हैं कि एसक्यूएलकनेक्शन को थ्रेड द्वारा एक्सेस किया गया हो, जो इसे बनाया गया हो। मुझे नहीं लगता कि ऐसा करना अवैध होगा, लेकिन आप वास्तव में अप्रत्याशित चीजों के लिए दरवाजा खोलते हैं। – dnewcome