ऐसा लगता है जब मैं ASP.NET MVC में एक अलग थ्रेड में एक कार्य चलाने के लिए, SimpleInjector प्रत्येक कॉल के लिए DbContext का एक नया उदाहरण बनाता है।
सरल इंजेक्टर v1.5 की RegisterPerWebRequest
जीवन शैली के व्यवहार और नीचे एक क्षणिक उदाहरण वापस जाने के लिए जब उदाहरणों एक वेब अनुरोध के संदर्भ (जहां HttpContext.Current
रिक्त है) के बाहर अनुरोध कर रहे हैं है। एक क्षणिक उदाहरण लौटाना सरल इंजेक्टर में एक डिज़ाइन दोष था, क्योंकि इससे अनुचित उपयोग को छिपाना आसान हो जाता है। Version 1.6 of the Simple Injector गलत तरीके से एक क्षणिक उदाहरण लौटने के बजाय अपवाद फेंक देगा, स्पष्ट रूप से संवाद करने के लिए कि आपने कंटेनर को गलत तरीके से कॉन्फ़िगर किया है।
जबकि (उदाहरण के StructureMap के लिए) कुछ आईओसी पुस्तकालयों प्रति-धागा-प्रति-webrequest के लिए एक मिश्रित जीवन शैली है, ऐसा लगता है सरल इंजेक्टर है नहीं एक
यह सही है कि सरल इंजेक्टर कुछ कारणों से मिश्रित जीवन शैली के लिए कोई अंतर्निहित समर्थन नहीं है। सबसे पहले यह एक विदेशी विशेषता है कि बहुत से लोगों को जरूरत नहीं है। दूसरा, आप किसी भी दो या तीन जीवन शैली को एक साथ मिश्रित कर सकते हैं, ताकि यह संकर का लगभग अंतहीन संयोजन होगा।और आखिरकार, यह (सुंदर) आसान है इसे स्वयं पंजीकृत करें।
यद्यपि आप Per Thread जीवन शैली के साथ Per Web Request मिश्रण कर सकते हैं, यह शायद बेहतर हो जब तुम Per Lifetime Scope साथ प्रति वेब अनुरोध मिश्रण, लाइफटाइम स्कोप के साथ के बाद से आप स्पष्ट रूप से शुरू करने और गुंजाइश खत्म (और जब गुंजाइश समाप्त हो जाती है DbContext
निपटान कर सकते हैं) होगा ।
Simple Injector 2 से और, आप Lifestyle.CreateHybrid विधि का उपयोग करके आसानी से किसी भी जीवन शैली को मिश्रित कर सकते हैं। Simple Injector: multi-threading in MVC3 ASP.NET
अद्यतन
अपने अद्यतन के बारे में:
var hybridLifestyle = Lifestyle.CreateHybrid(
() => HttpContext.Current != null,
new WebRequestLifestyle(),
new LifetimeScopeLifestyle());
// Register as hybrid PerWebRequest/PerLifetimeScope.
container.Register<DbContext, MyDbContext>(hybridLifestyle);
एक और Stackoverflow सवाल है कि इस विषय पर एक सा गहरी, आप एक बार देख लेने के लिए चाहते हो सकता है में चला जाता है नहीं है: यहाँ एक उदाहरण है। आप लगभग वहाँ हैं। पृष्ठभूमि थ्रेड पर चलने वाले आदेशों को लाइफटाइम स्कोप के भीतर चलाने की आवश्यकता है, इसलिए आपको इसे स्पष्ट रूप से प्रारंभ करना होगा। यहां नई चाल पर BeginLifetimeScope
पर कॉल करना है, लेकिन वास्तविक कमांड हैंडलर (और इसकी निर्भरता) बनने से पहले। दूसरे शब्दों में, ऐसा करने का सबसे अच्छा तरीका सजावट के अंदर है। के बाद से इस डेकोरेटर दोनों एक नया धागा पर आदेशों चलाता है,
public class AsyncCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> where TCommand : ICommand
{
private readonly Container _container;
private readonly Func<ICommandHandler<TCommand>> _factory;
public AsyncCommandHandlerDecorator(Container container,
Func<ICommandHandler<TCommand>> factory)
{
_container = container;
_factory = factory;
}
public void Handle(TCommand command)
{
ThreadPool.QueueUserWorkItem(_ =>
{
using (_container.BeginLifetimeScope())
{
// Create new handler in this thread
// and inside the lifetime scope.
var handler = _factory();
handler.Handle(command);
}
});
}
}
जहां शुद्धतावादियों की वकालत कि SOLID सिद्धांतों चिल्लाना होगा कि इस वर्ग के Single Responsibility Principle उल्लंघन कर रहा है:
सबसे आसान समाधान अपने AsyncCommandHandlerDecorator
अद्यतन करने के लिए गुंजाइश को जोड़ने के लिए है और एक नया जीवनकाल गुंजाइश शुरू करता है। मैं इसके बारे में ज्यादा चिंता नहीं करता, क्योंकि मुझे लगता है कि बैकग्राउंड थ्रेड शुरू करने और जीवन भर के दायरे को शुरू करने के बीच घनिष्ठ संबंध है (आप वैसे भी किसी के बिना किसी का उपयोग नहीं करेंगे)। लेकिन फिर भी, आप आसानी से AsyncCommandHandlerDecorator
अछूता छोड़ दें और इस प्रकार एक नया LifetimeScopedCommandHandlerDecorator
बना सकते हैं:
public class LifetimeScopedCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand> where TCommand : ICommand
{
private readonly Container _container;
private readonly Func<ICommandHandler<TCommand>> _factory;
public LifetimeScopedCommandHandlerDecorator(Container container,
Func<ICommandHandler<TCommand>> factory)
{
_container = container;
_factory = factory;
}
public void Handle(TCommand command)
{
using (_container.BeginLifetimeScope())
{
// The handler must be created inside the lifetime scope.
var handler = _factory();
handler.Handle(command);
}
}
}
जिस क्रम में इन सज्जाकार पाठ्यक्रम आवश्यक की है पंजीकृत हैं, के बाद से AsyncCommandHandlerDecorator
LifetimeScopedCommandHandlerDecorator
लपेट चाहिए। इसका मतलब है कि LifetimeScopedCommandHandlerDecorator
पंजीकरण पहले आना चाहिए: और अधिक विस्तार से इस बारे में
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(LifetimeScopedCommandHandlerDecorator<>),
backgroundCommandCondition);
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(AsyncCommandHandlerDecorator<>),
backgroundCommandCondition);
This old Stackoverflow question बात करती है। आपको निश्चित रूप से एक नज़र रखना चाहिए।
संबंधित: http://stackoverflow.com/questions/11041601/simple-injector-multi-threading-in-mvc3-asp-net – Steven
संबंधित: http://stackoverflow.com/questions/10304023/simpleinjector-is -इस-द-राइट-वे-टू-रजिस्टरमैन्योरोपेंजेनेरिक-कब-मेरे पास – Steven