संस्करण के लिए, आप शायद प्रत्येक संस्करण के लिए एक अंतरफलक और 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 का उपयोग कर संस्करण का समर्थन कर सकता है।