2013-02-25 13 views
5

मैं प्लगइन प्रबंधन आवश्यकता को हल करने के लिए एमईएफ का उपयोग करने की सोच रहा हूं। अस्पष्टता में यह "कोई कठोर निर्भरता" नहीं कहता है, लेकिन जहां तक ​​मैं देख सकता हूं, आयात/निर्यात इंटरफेस पर एक कठिन निर्भरता है।एमईएफ और वर्जनिंग

मेरी चिंता यह है। मेरा विस्तार योग्य ऐप मेरे द्वारा लिखा गया है। प्लगइन्स तीसरे पक्ष द्वारा लिखे गए हैं। तो मान लें कि हम सभी V1 से शुरू होते हैं। मेरा ऐप IPlugin इंटरफ़ेस को परिभाषित करता है कि प्लगइन 'भागों' को कार्यान्वित करने की आवश्यकता है। हम ऐप को तैनात करते हैं और उपयोगकर्ता तीसरे पक्ष के प्लगइन का एक समूह स्थापित करते हैं। सब ठीक है और अच्छा है।

अब मैं अपना ऐप अपग्रेड करता हूं और मैं प्लगइन इंटरफ़ेस में एक नई विधि जोड़ना चाहता हूं। जिस तरह से मैं इसे देखता हूं मेरे पास 2 विकल्प हैं:

  1. इंटरफ़ेस संपादित करें - शायद खराब, और यह मौजूदा प्लगइन तोड़ देगा क्योंकि वे अब इंटरफ़ेस को सही ढंग से कार्यान्वित नहीं करेंगे।
  2. एक नए 'V2' इंटरफेस, कि मूल

    सार्वजनिक इंटरफ़ेस IPluginV2 से विरासत बनाएँ: IPlugin {}

अब मैं एक समस्या है। मेरे उपयोगकर्ताओं के पास IPlugin लागू करने वाले तृतीय पक्ष प्लगइन का एक समूह है, लेकिन अब मुझे उन्हें IPluginV2 लागू करने की आवश्यकता है। मुझे लगता है कि डेवलपर्स नए इंटरफ़ेस को लागू करने तक इन तृतीय पक्ष प्लगइन्स अब काम नहीं करेंगे।

क्या एमईएफ के पास इस स्थिति को संभालने का कोई तरीका है? मैं वास्तव में एक ऐसे तरीके की तलाश में हूं जो मुझे अपने ऐप को विकसित करने देता है जबकि पुराना प्लगइन्स पुनर्निर्मित किए बिना काम करना जारी रखता है। क्या इसे संभालने का सबसे अच्छा तरीका है?

उत्तर

1

बस एक सुझाव की जोड़ी (जो मैं परीक्षण नहीं किया) आपके लिए एक समाधान बुद्धिशीलता मदद मिल सकती है:

  1. तो MEF का उपयोग कर, संस्करणों में से प्रत्येक के लिए अलग अलग AggregateCatalog का उपयोग करें। इस तरह आप वी 1 और वी 2 प्लगइन्स दोनों को बनाए रख सकते हैं

  2. यदि एमईएफ का उपयोग नहीं किया जाता है, तो तीसरे पक्ष के गतिशील लोड किए गए डीएलएल को वर्तमान इंटरफ़ेस संस्करण को वापस कर देना चाहिए और आप यह चुन सकते हैं कि आप कौन से कॉल कर सकते हैं संस्करण संख्या

क्या इससे मदद मिली?

चीयर्स, dimamura

11

संस्करण के लिए, आप शायद प्रत्येक संस्करण के लिए एक अंतरफलक और adapter pattern उन दोनों के बीच जाने के लिए चाहते हैं। यह है कि कैसे System.AddIn वर्जनिंग हैंडल करता है, और यह भी एमईएफ के लिए काम करता है।

मान लीजिए कि हम V1 अपने आवेदन के के लिए निम्नलिखित प्रकार करते हैं:

public interface IPlugin 
{ 
    string Name { get; } 
    string Publisher { get; } 
    string Version { get; } 

    void Init(); 
} 

यह हमारे V1 प्लगइन अवगत अनुप्रयोग के लिए केवल अनुबंध है। यह असेंबली Contracts.v1 में निहित है।

[Export(typeof(IPlugin))] 
public class SomePlugin : IPlugin 
{ 
    public string Name { get { return "Some Plugin"; } } 

    public string Publisher { get { return "Publisher A"; } } 

    public string Version { get { return "1.0.0.0"; } } 

    public void Init() { } 

    public override string ToString() 
    { 
     return string.Format("{0} v.{1} from {2}", Name, Version, Publisher); 
    } 
} 

कौन सा IPlugin के रूप में निर्यात किया जाता है:

फिर हम एक V1 प्लगइन है। यह असेंबली Plugin.v1 में निहित है और मेजबान के अनुप्रयोग आधार पथ के तहत "प्लगइन्स" फ़ोल्डर पर प्रकाशित है।

अंत में V1 मेजबान:

class Host : IDisposable 
{ 
    CompositionContainer _container; 

    [ImportMany(typeof(IPlugin))] 
    public IEnumerable<IPlugin> Plugins { get; private set; } 

    public Host() 
    { 
     var catalog = new DirectoryCatalog("plugins"); 
     _container = new CompositionContainer(catalog); 
     _container.ComposeParts(this); 
    } 

    public void Dispose() { _container.Dispose(); } 
} 

जो फ़ोल्डर "प्लग इन" में मिले सभी IPlugin भागों आयात करता है।

फिर हम V2 प्रकाशित करने का निर्णय और हम ठेके versionless की आवश्यकता होगी क्योंकि हम संस्करण प्रदान करना चाहते हैं: एक नया संपत्ति और एक संशोधित विधि हस्ताक्षर के साथ

public interface IPluginV2 
{ 
    string Name { get; } 
    string Publisher { get; } 
    string Version { get; } 
    string Description { get; } 

    void Init(IHost host); 
} 

। प्लस हम मेजबान के लिए एक इंटरफेस जोड़ें:

public interface IHost 
{ 
    //Here we can add something useful for a plugin. 
} 

इन दोनों विधानसभा Contracts.v2 में शामिल हैं।

संस्करण अनुमति देने के लिए हम V1 से V2 के लिए एक प्लगइन एडाप्टर जोड़ें:

class V1toV2PluginAdapter : IPluginV2 
{ 
    IPlugin _plugin; 

    public string Name { get { return _plugin.Name; } } 

    public string Publisher { get { return _plugin.Publisher; } } 

    public string Version { get { return _plugin.Version; } } 

    public string Description { get { return "No description"; } } 

    public V1toV2PluginAdapter(IPlugin plugin) 
    { 
     if (plugin == null) throw new ArgumentNullException("plugin"); 
     _plugin = plugin; 
    } 

    public void Init(IHost host) { plugin.Init(); } 

    public override string ToString() { return _plugin.ToString(); } 
} 

यह केवल IPlugin से IPluginV2 के लिए adapts। यह एक निश्चित विवरण देता है और Init में यह होस्ट तर्क के साथ कुछ भी नहीं करता है लेकिन यह V1 अनुबंध से पैरामीटर रहित Init पर कॉल करता है।

और अंत में V2 मेजबान:

class HostV2WithVersioning : IHost, IDisposable 
{ 
    CompositionContainer _container; 

    [ImportMany(typeof(IPluginV2))] 
    IEnumerable<IPluginV2> _pluginsV2; 

    [ImportMany(typeof(IPlugin))] 
    IEnumerable<IPlugin> _pluginsV1; 

    public IEnumerable<IPluginV2> Plugins 
    { 
     get 
     { 
      return _pluginsV1.Select(p1 => new V1toV2PluginAdapter(p1)).Concat(_pluginsV2); 
     } 
    } 

    public HostV2WithVersioning() 
    { 
     var catalog = new DirectoryCatalog("plugins"); 
     _container = new CompositionContainer(catalog); 
     _container.ComposeParts(this); 
    } 

    public void Dispose() { _container.Dispose(); } 
} 

जो दोनों IPlugin और IPluginV2 भागों आयात करता है, IPluginV2 में प्रत्येक IPlugin adapts और सभी की खोज की plugins की एक concatenated अनुक्रम उजागर करता है। अनुकूलन पूरा होने के बाद, सभी प्लगइन्स को V2 प्लगइन के रूप में माना जा सकता है।

तुम भी मेजबान के इंटरफेस पर एडाप्टर पैटर्न का उपयोग V2 प्लगइन्स V1 मेजबानों के साथ काम करने के लिए अनुमति देने के लिए कर सकते हैं।

एक और दृष्टिकोण autofac आईओसी होगा जो integrate एमईएफ के साथ कर सकता है और adapters का उपयोग कर संस्करण का समर्थन कर सकता है।

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