6

मैं EntityFramework का उपयोग कर रहा हूं और पृष्ठभूमि नौकरी कक्षाओं के समूह में एक सामान्य भंडार और इकाई-कार्य पैटर्न लागू कर रहा हूं। जॉब्स क्लासेस यूनिटी डी का उपयोग करके बनाए जाते हैं ताकि उन्हें निर्भरताओं से इंजेक्शन दिया जा सके, जो ज्यादातर भंडार और UnitOfWork ऑब्जेक्ट हैं। रेपॉजिटरीज़ और यूनिट ऑफ वर्क को ईएफ DbContext साझा करना चाहिए।यूनिटी PerThreadLifetimeManager और कार्य

एक आम काम इस प्रकार दिखाई देगा:

public class CommonJob : IJob, IDisposable 
{   
    private IRepo<SomeEntity> _repo; 
    private IUnitOfWork _uow; 

    public CommonJob(IRepo<SomeEntity> repo, IUnitOfWork uow) 
    { 
     _repo = repo; 
     _uow = uow; 
    } 

    public void RunJob() 
    { 
     // do stuff here 
    } 

    public void Dispose() 
    { 
     _uow.Commit(); 
     _uow.Dispose(); 
    } 
} 

सभी नौकरियों नए कार्य के भीतर चलाए जा रहे हैं, इस

Task.Factory.StartNew(() => { 
    // container is UnityContainer 
    var job = container.Resolve<CommonJob>(); 
    job.RunJob(); 
    job.Dispose(); 
}); 

की तरह कुछ और मैं इकाई के- काम करते हैं और खजाने पंजीकृत कर लिया है PerThreadLifetimeManager का उपयोग करके एकता के साथ, यह सोचकर कि एक कार्य (और उस नौकरी वस्तु में) के संदर्भ में पंजीकृत उदाहरणों को साझा करने की अनुमति होगी, लेकिन बाहर नहीं।

जो मुद्दा मैं कर रहा हूं वह यह है कि कभी-कभी नौकरियों को डिस्पोजेड ऑब्जेक्ट्स से इंजेक्शन दिया जाएगा, जो स्पष्ट रूप से बहुत अच्छा नहीं है। मैं पढ़ रहा हूं कि Task.Factory.StartNew() हमेशा एक नया धागा उपयोग नहीं करता है। क्या इसका मतलब यह है कि PerThreadLifetimeManager कार्यों के बीच वस्तुओं को साझा करेगा? यदि यह सच है, तो क्या एकता के साथ ऑब्जेक्ट लिफ्टटाइम को प्रबंधित करने का एक और तरीका है, जो प्रत्येक कार्य को अलगाव में काम करने की अनुमति देगा, चाहे वह थ्रेड चल रहा हो?

संपादित करें:

चयनित जवाब नीचे भी वही करता है करते हैं, मैं हर काम के लिए निर्भरता अलगाव को प्राप्त करने के HierarchicalLifetimeManager और बच्चे कंटेनरों का इस्तेमाल किया गया।

यहाँ एक उदाहरण है:

// registering the dependencies, 
// these should be singletons, but only within the context of one job 
_container.Register(typeof(IRepo<>), typeof(Repo<>), new HierarchicalLifetimeManager()) 
      .Register<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager()); 

// starting a new job 
Task.Factory.StartNew<IUnityContainer>(() => 
{ 
    // create a child container to remove instance sharing between tasks 
    var childContainer = _container.CreateChildContainer(); 

    // figure out and resolve the job class from the child container 
    // this will make sure that different jobs do not share instances 
    var jobType = GetJobType(); 
    var job = childContainer.Resolve(jobType) as IJob; 

    job.RunJob(); 

    return childContainer; 
}).ContinueWith(previousTask => { 
    // when the job is done, dispose of the child container 
    task.Result.Dispose(); 
}); 

उत्तर

6

आप निपटाए वस्तुओं क्योंकि समानांतर पुस्तकालय एक थ्रेड पूल का उपयोग करता मिलता है, और एकता पूल के एक ही धागे के लिए एक ही वस्तु देता है।

यदि आप पोस्ट किए गए तरीके से कंटेनर का उपयोग करते हैं, तो मैं आपको PerResolveLifetimeManager का उपयोग करने का सुझाव देता हूं। इस तरह, जब आप किसी ऑब्जेक्ट को हल करते हैं तो संपूर्ण रिज़ॉल्यूशन ग्राफ़ एक ही उदाहरण साझा करता है लेकिन उदाहरण प्रति संकल्प अद्वितीय है: Resolve पर कॉल करते समय प्रत्येक कार्य का अपना उदाहरण होगा।

+1

आपका उत्तर सही है, लेकिन मैं सिर्फ यह जोड़ना चाहता था कि मैं 'HieararchicalLiftetimeManager' का उपयोग करके समाप्त हुआ और कार्य में एक बच्चा कंटेनर बना रहा। ऐसा इसलिए है क्योंकि मुझे नौकरी कक्षाओं में से किसी एक से गतिशील रूप से कुछ सेवाओं को हल करने के लिए कंटेनर का उपयोग करने की आवश्यकता है। मुझे पता है कि एक कंटेनर का उपयोग एक सेवा लोकेटर के रूप में एक कोड गंध है, लेकिन इस तरह यह स्थापित किया गया है, और इसे ठीक करने के लिए अभी कोई समय नहीं है ... – Pinetree

+1

@Pinetree कोई भी मौका आप यह दिखा सकते हैं कि आपने यह कैसे किया? धन्यवाद – nfplee

+0

@nfplee मेरे पास घर पर कोड नहीं है और मुझे इसे मेरे सिर के शीर्ष पर याद नहीं है। जब मैं काम करता हूं तो मैं सोमवार को जो कुछ करता हूं उसे पोस्ट करूंगा। – Pinetree

संबंधित मुद्दे