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

मैंने कोड में निर्भरता प्राप्त करने के लिए कई अन्य तरीकों की कोशिश की है, बिना किसी सफलता के, जिसमें एक आईस्कोप फैक्ट्री का पर्दाफाश करने के लिए निनजेक्ट कारखानों का उपयोग और एक फंक निर्भरता शामिल है। बाद के मामले में, समस्या यह है कि (मुझे लगता है) निनजेक्ट INotifyWhenDisposed को तार नहीं करता है। घटना का निपटान करें क्योंकि बाध्यकारी लक्ष्य Func स्वयं एक आईडीस्पोजेबल नहीं है।

वैसे भी, मैं जो हासिल करने की कोशिश कर रहा हूं उसका कोड यहां दिया गया है।

आईओसी

 Kernel
     .Bind<MyDbContext>()
     .ToSelf()
     .InScope(x => CommandScope.Current)
     .OnDeactivation(x => x.SaveChanges());

कमांडस्कोप

public class CommandScope : INotifyWhenDisposed
{
    public event Dispose;

    public bool IsDisposed { get; private set; }

    public static CommandScope Current { get; private set; }

    public static CommandScope Create()
    {
        CommandScope result = new CommandScope();
        Current = result;
        return result;
    }

    public void Dispose()
    {
        IsDisposed = true;
        Current = null;
        Dispose?.Invoke(this, EventArgs.Empty);
    }
}

मेरे डोमेन के अंदर...

public class Pipeline<TRequest, TResponse>
{
    readonly IRequestHandler<TRequest, TResponse> innerHandler;

    public Pipeline(IRequestHandler<TRequest, TResponse> handler)
    {
        innerHandler = handler;
    }

    public TResponse Handle(TRequest request)
    {
         using(CommandScope.Create())
         {
             handler.Handle(request);
         }
    }
}
0
Matt 31 जुलाई 2017, 15:41
लेकिन आपका पाइपलाइन वर्ग बल्कि कुछ ढांचागत कोड है, इसलिए आप इसे अपने डोमेन तर्क सहित एक से भिन्न प्रोजेक्ट में निकाल सकते हैं। या आपको कोई और समस्या है?
 – 
Jan Muncinsky
31 जुलाई 2017, 17:54

2 जवाब

आप डेकोरेटर पैटर्न (इंटरफ़ेस की आवश्यकता है) का उपयोग कर सकते हैं और केवल डेकोरेटर INotifyWhenDisposed इंटरफ़ेस को लागू कर सकते हैं - फिर डेकोरेटर को कंपोज़िशन रूट में रखें - वहाँ आपको वैसे भी एक निनजेक्ट संदर्भ की आवश्यकता है।

वैकल्पिक रूप से, आप एक फंक फैक्ट्री का उपयोग कर सकते हैं, एक IDisposable बना सकते हैं जो वास्तविक INotifyWhenDisposed लागू करता है (उपभोग करने वाले पुस्तकालय को इसके बारे में जानने की आवश्यकता नहीं है)। अपने कंपोज़िशन रूट में इंस्टेंस को एक्सेस करते समय, आप अभी भी इसे INotifyWhenDisposed पर डाल सकते हैं (वास्तव में यह आवश्यक नहीं हो सकता है)। उदाहरण के लिए:

.InScope(x => (INotifyWhenDisposed)CommandScope.Current)

डिजाइन पर एक टिप्पणी: मैं CommandScope को दो वर्गों में विभाजित करने की सिफारिश करूंगा: एक कारखाना और वास्तविक दायरा। साथ ही, लंबे समय में आप शायद यह सुनिश्चित करके बहुत सारे सिरदर्द से बचा सकते हैं कि एक नया दायरा (Create द्वारा बनाया गया) एक पुराने को प्रतिस्थापित नहीं करता है जिसे अभी तक निपटाया नहीं गया है। अन्यथा आप अपने द्वारा पेश किए गए लीक से बहुत अच्छी तरह चूक सकते हैं।

2
BatteryBackupUnit 1 अगस्त 2017, 09:51

निनजेक्ट के ICache से स्कोप ऑब्जेक्ट को साफ़ करने से निनजेक्ट को स्कोप द्वारा नियंत्रित सभी इंस्टेंस को बंद करने और निपटाने के लिए मजबूर किया जाएगा:

var activationCache = Kernel.Get<Ninject.Activation.Caching.ICache>();
activationCache.Clear(CommandScope.Current);

आप अपने सिंगलटन पैटर्न कमांडस्कोप के बेहतर विकल्प के लिए NamedScope एक्सटेंशन पर भी विचार कर सकते हैं।

0
dave thieben 8 अगस्त 2017, 18:44