एकाधिक सत्र कारखानों को पंजीकृत करना आसान है - समस्या की आवश्यकता होने पर समस्या सही चुन रही है। उदाहरण के लिए, मान लें कि हमारे पास कुछ प्रकार की प्रयोगशाला है जिसमें कई डेटाबेस हैं। प्रत्येक प्रयोगशाला में उस स्थान के लिए एक स्थान और एकाधिक नमूने होते हैं। हमारे पास एक नमूना भंडार हो सकता है जो मॉडल। प्रत्येक स्थान की पहचान करने के लिए एक अनूठी कुंजी होती है (उदा। "लैबएक्स", "लैब", "ब्लैकमेसा")। हम app.config फ़ाइल में डेटाबेस कनेक्शन स्ट्रिंग के नाम के रूप में उस अद्वितीय कुंजी का उपयोग कर सकते हैं। इस उदाहरण में, हमारे पास app.config फ़ाइल में तीन कनेक्शन स्ट्रिंग होंगे।
<connectionStrings>
<add name="LabX" connectionString="Data Source=labx;User ID=someuser;Password=somepassword"/>
<add name="LabY" connectionString="Data Source=laby;User ID=someuser;Password=somepassword"/>
<add name="BlackMesa" connectionString="Data Source=blackmesa;User ID=freemang;Password=crowbar"/>
</connectionStrings>
इस प्रकार, हम प्रत्येक कनेक्शन स्ट्रिंग के लिए एक अनूठा सत्र कारखाने की आवश्यकता है: यहाँ एक नमूना ConnectionStrings अनुभाग है। चलो एक NamedSessionFactory कि ISessionFactory लपेटता बनाएँ:
public interface INamedSessionFactory
{
public string Name { get; } // The name from the config file (e.g. "BlackMesa")
public ISessionFactory SessionFactory { get; }
}
public class NamedSessionFactory : INamedSessionFactory
{
public string Name { get; private set; }
public ISessionFactory SessionFactory { get; private set; }
public NamedSessionFactory(string name, ISessionFactory sessionFactory)
{
Name = name;
SessionFactory = sessionFactory;
}
}
अब हम अपने AppSessionFactory थोड़ा संशोधित करने की आवश्यकता। सबसे पहले, जो आपने बनाया है वह एक सत्र फैक्ट्री फैक्ट्री है - यह वह नहीं है जिसे हम ढूंढ रहे हैं। हम अपने फैक्ट्री को एक स्थान देना चाहते हैं और सत्र सत्र नहीं लेना चाहते हैं। Fluent NHibernate हमें सत्र कारखानों देता है।
public interface IAppSessionFactory
{
ISession GetSessionForLocation(string locationKey);
}
यहाँ चाल निर्माता में INamedSessionFactory वस्तुओं की एक सूची को स्वीकार है। स्ट्रक्चर मैप हमें उन सभी INMESessionFactory ऑब्जेक्ट्स को देना चाहिए जिन्हें हमने पंजीकृत किया है। हम एक सेकंड में पंजीकरण करेंगे।
public class AppSessionFactory : IAppSessionFactory
{
private readonly IList<INamedSessionFactory> _factories;
public AppSessionFactory(IEnumerable<INamedSessionFactory factories)
{
_factories = new List<INamedSessionFactory>(factories);
}
यह वह जगह है जहां जादू होता है। एक स्थान कुंजी को देखते हुए, हम कारखानों की हमारी सूची के माध्यम से एक ही नाम के साथ एक स्थान की तलाश करते हैं, फिर उसे एक सत्र खोलने और कॉलर पर वापस करने के लिए कहें।
public ISession GetSessionForLocation(string locationKey)
{
var sessionFactory = _factories.Where(x => x.Name == locationKey).Single();
return sessionFactory.OpenSession();
}
}
अब हम सभी को एक साथ तार दें।
internal class NHibernateRegistry : Registry
{
public NHibernateRegistry()
{
हम अपने app.config फ़ाइल में कनेक्शन तार के सभी के माध्यम से लूप करने जा रहे हैं (वहाँ इस उदाहरण में उनमें से तीन हो जाएगा) और हर एक के लिए एक INamedSessionFactory वस्तु रजिस्टर।
foreach (ConnectionStringSettings location in ConfigurationManager.ConnectionStrings)
{
For<INamedSessionFactory>()
.Singleton()
.Use(x => new NamedSessionFactory(
location.Name,
GetSessionFactory(location.ConnectionString));
}
हमें IAppSessionFactory पंजीकृत करने की भी आवश्यकता है।
For<IAppSessionFactory>()
.Singleton()
.Use<AppSessionFactory>();
}
आप देखेंगे कि हमने कारखाने वर्ग से इस तर्क को स्थानांतरित कर दिया है ...फ्लुएंट एनएचबेर्नेट से सत्र कारखानों के निर्माण के लिए ये सहायक तरीके हैं।
private static ISessionFactory GetSessionFactory(string connectionString)
{
return GetConfig(connectionString)
.BuildSessionFactory();
}
public static FluentConfiguration GetConfig(string connectionString)
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(x => x.Is(connectionString)))
.Mappings(
x => x.FluentMappings.AddFromAssemblyOf<AppEntity>());
}
}
ऐसा करना चाहिए! चलो हमारे नमूने में प्राप्त करने के लिए भंडार बनाते हैं ...
public class SampleRepository
{
private readonly IAppSessionFactory _factory;
public SampleRepository(IAppSessionFactory factory)
{
_factory = factory;
}
public IEnumerable<Sample> GetSamplesForLocation(Location location)
{
using (ISession session = _factory.GetSessionForLocation(location.Key)
{
foreach (Sample sample in session.Query<Sample>())
yield return sample;
}
}
}
अब आप SampleRepository का एक उदाहरण हो और तीन डेटाबेस हम app.config में पंजीकृत किया है में से किसी से नमूने को खींचने के लिए GetSamplesForLocation विधि का उपयोग कर सकते हैं। हालांकि ब्लैकमेसा से बचना चाहते हैं। मैं समझता हूं कि वहां समस्याएं थीं।
मैं शायद ध्यान देना चाहिए कि यह साल हो गया है के बाद से मैं StructureMap या NHibernate का उपयोग किया है - तो मैं वहाँ कुछ खराब कर दिया हो सकता है। लेकिन मूल पैटर्न ध्वनि होना चाहिए। आशा करता हूँ की ये काम करेगा! –
एक वास्तव में उपयोगी जवाब। मैं वर्तमान में StAcutreMap के TheInstanceNamed() को DAO को सत्र फ़ैक्टरीज़ असाइन करने के लिए उपयोग कर रहा हूं, जो ठीक काम करता प्रतीत होता है। मेरे पास कुछ समय अतिरिक्त समय होने पर आपके सुझावों को लागू करने के लिए देखेंगे। धन्यवाद। – TonE