2012-08-02 13 views
5

के तहत विंडसर में रेवेनडीबी सत्र का प्रबंधन मैं एमवीसी 4 प्रोजेक्ट में एनएस सर्विसबस (3.2.2), रावेनडीबी (1.2.2017-अस्थिर) और विंडसर (3.0.0.4001) का उपयोग कर रहा हूं।एनएस सर्विसबस

मैं एक IHandleMessages वर्ग कि 3 अलग संदेशों को संभालती है, और है कि इस तरह के रूप में एक IDocumentSession एक संपत्ति की जरूरत है, और इसलिए परिभाषित करता है:

public IDocumentSession DocumentSession { get; set; } 

मैं NServiceBus 'website

से RavenDbUnitOfWork कार्यान्वयन कॉपी किया है

मैं इस प्रकार मेरी विंडसर कंटेनर में IDocumentStore, IDocumentSession और IManageUnitsOfWork पंजीकृत कर लिया है:

container.Register(
      Component 
       .For<IManageUnitsOfWork>() 
       .ImplementedBy<RavenUnitOfWork>() 
       .LifestyleTransient() 
      ); 
container.Register(
      Component 
       .For<IDocumentStore>() 
       .UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore) 
       .LifestyleSingleton(), 
      Component 
       .For<IDocumentSession>() 
       .UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession()) 
       .LifestyleTransient() 
      ); 

NServiceBus मेरी कंटेनर का उपयोग कर कॉन्फ़िगर किया गया है:

Configure.With() 
     .CastleWindsorBuilder(container); 

मैं समस्या यह है कि UnitOfWork और संदेश हैंडलर DocumentSession के विभिन्न उदाहरणों प्राप्त सामना कर रहा हूँ। इसका अर्थ यह है कि संदेश हैंडलर में सत्र में संग्रहीत ऑब्जेक्ट्स सहेजे नहीं जाते हैं, क्योंकि SaveChanges() को एक अलग दस्तावेज़ सत्र पर कॉल किया जाता है।

क्षणिक जीवनशैली को हटाने से विभिन्न प्रकार की समस्याएं होती हैं, जिसके परिणामस्वरूप रावेनडीबी से ऑब्जेक्ट्स अपडेट करते समय समेकन/संघर्ष होते हैं, क्योंकि (संभवतः) संदेश हैंडलर दस्तावेज़ सत्र का एक ही उदाहरण प्राप्त करता रहता है, जिसमें अद्यतन का कैश संस्करण होता है वस्तु।

अद्यतन:

के रूप में सुझाव दिया है, मैं, विंडसर में IDocumentSession के पंजीकरण को बदलने की कोशिश की है इस तरह घेरा जीवन शैली के लिए,:

Component 
    .For<IDocumentSession>() 
    .UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession()) 
    .LifestyleScope() 

यह अपवाद जब कंटेनर की कोशिश करता का कारण बनता है एमवीसी नियंत्रक को हल करने के लिए, यह कहकर कि दायरा नहीं मिला था, और पूछ रहा था कि क्या मैं BeginScope() को कॉल करना भूल गया था।

+0

आप परिभाषा DocumentStoreHolder को जोड़ सकते हैं? –

उत्तर

4

आपको प्रति संदेश का दायरा होना चाहिए, क्षणिक या सिंगलटन नहीं।

+0

+1, लाइफसीले टाइप। स्कॉप्ड वह है जो आप चाहते हैं https://github.com/NServiceBus/NServiceBus/blob/master/src/impl/ObjectBuilder/ObjectBuilder.CastleWindsor/WindsorObjectBuilder.cs#L175 –

+0

इसके अलावा, ऐसा क्यों नहीं है RavenUnitOfWork के लिए प्रयुक्त - दस्तावेज़ सत्र उदाहरण का प्रबंधन? – SaguiItay

+1

यूओडब्ल्यू बस कॉल करने के लिए है .वेव चेंज। कंटेनर द्वारा निर्माण और निपटान किया जाता है। यही कारण है कि आपको स्कोप्ड का उपयोग करने की आवश्यकता है ताकि आपको प्रति संदेश –

0

मुझे लगता है कि आपके एमवीसी नियंत्रक के पास IDocumentStore पर प्रत्यक्ष निर्भरता है। आपको वेब से प्रत्येक अनुरोध से पहले कंटेनर। बेजिनस्कोप() को कॉल करने की आवश्यकता है। आप या तो इसे एक्शन फ़िल्टर विशेषता http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute.aspx या नियंत्रक पर एओपी पहलू के रूप में कर सकते हैं http://cangencer.wordpress.com/2011/06/02/asp-net-mvc-3-aspect-oriented-programming-with-castle-interceptors/

0

समस्या यह है कि एक ही कंटेनर में IDocumentSession साझा करते समय एक asp.net mvc वेबसाइट में nservicebus का उपयोग करते समय आपको विभिन्न जीवन शैली की आवश्यकता होती है।

एएसपी.नेट एमवीसी के लिए आपको एक PerWebRequest जीवन शैली की आवश्यकता है और NServiceBus के लिए आपको स्कॉप्ड लाइफस्टाइल की आवश्यकता है।

कि मैं महल योगदान परियोजना में संकर जीवन शैली कोड का उपयोग किया है करने के लिए: https://github.com/castleprojectcontrib/Castle.Windsor.Lifestyles/tree/master/Castle.Windsor.Lifestyles

जब एक ASP.NET संदर्भ से फोन कर रहा है, यह WebRequestScopeAccessor उपयोग करता है। NServicebus के लिए आपको लाइफटाइमस्कोप एक्सेसर की आवश्यकता है।यहाँ

container.Register(Component.For<IDocumentSession>().LifestyleScoped<HybridPerWebRequestLifetimeScopeScopeAccessor>().UsingFactoryMethod(() => RavenDbManager.DocumentStore.OpenSession())); 

और मुझे स्विच करने से पहले इस्तेमाल किया राइनो सेवा बस के लिए एक कार्यान्वयन है: यह योगदान परियोजना में नहीं है, लेकिन जोड़ना आसान है:

public class HybridPerWebRequestLifetimeScopeScopeAccessor : HybridPerWebRequestScopeAccessor 
{ 
    public HybridPerWebRequestLifetimeScopeScopeAccessor() 
     : base(new LifetimeScopeAccessor()) 
    { 
    } 
} 

और अपना पंजीकरण कोड में आप की तरह कुछ की जरूरत है nservicebus रहे हैं:

https://gist.github.com/4655544

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