Plugin inheritance architecture
-
Hello guys and girls, I've got a generic architecture best principals question for you I as hoping people could give me some pointers on (or at least, generate some discussion over). The issue I've just encountered is as follows: I'm generating a plugin for a service. My plugin will be compiled as a stand alone dll and called from an application. There are two stages of execution for the plugin: 1. Set up as part of a winforms application, then 2) execution as part of a windows service. In generating the setup information I specify a list of types of "Email Processor" class to use, where EmailProcessor is an abstract class and each type of email processor extends that abstract class to create in instance class. In saving the settings, the list of EmailProcessors was to be saved using XmlSerialisation (this is functionality of the parent application and not my plugin), which throws an error since the type of the EmailProcessor is dynamic. I can't implement any sort of custom XmlSerialisation so I have had to make the abstract EmailProcessor class into a real (non-abstract) class and then throw a NotImplementedException from each of its methods. This has obviously broken the basic inheritance model slightly - not so much as to be truly irritating but enough to make me think there was probably a more correct way of approaching the issue. Can anyone suggest to me what I should have done to allow EmailProcessors to maintain their inheritance model but overcome the issues I had with getting round the XmlSerialisation of dynamic types that I had no control over? Any thoughts greatly appreciated. Cheers, Adam
-
Hello guys and girls, I've got a generic architecture best principals question for you I as hoping people could give me some pointers on (or at least, generate some discussion over). The issue I've just encountered is as follows: I'm generating a plugin for a service. My plugin will be compiled as a stand alone dll and called from an application. There are two stages of execution for the plugin: 1. Set up as part of a winforms application, then 2) execution as part of a windows service. In generating the setup information I specify a list of types of "Email Processor" class to use, where EmailProcessor is an abstract class and each type of email processor extends that abstract class to create in instance class. In saving the settings, the list of EmailProcessors was to be saved using XmlSerialisation (this is functionality of the parent application and not my plugin), which throws an error since the type of the EmailProcessor is dynamic. I can't implement any sort of custom XmlSerialisation so I have had to make the abstract EmailProcessor class into a real (non-abstract) class and then throw a NotImplementedException from each of its methods. This has obviously broken the basic inheritance model slightly - not so much as to be truly irritating but enough to make me think there was probably a more correct way of approaching the issue. Can anyone suggest to me what I should have done to allow EmailProcessors to maintain their inheritance model but overcome the issues I had with getting round the XmlSerialisation of dynamic types that I had no control over? Any thoughts greatly appreciated. Cheers, Adam
Look at the article I posted on creating a plug-in architecture at http://www.codeproject.com/useritems/TaskPlugin.asp. There is a good use of it in the Task Scheduling application that I wrote at http://www.codeproject.com/useritems/Guadagno_task_scheduler.asp Hope this helps, Joseph Guadagno http://www.josephguadagno.net
-
Hello guys and girls, I've got a generic architecture best principals question for you I as hoping people could give me some pointers on (or at least, generate some discussion over). The issue I've just encountered is as follows: I'm generating a plugin for a service. My plugin will be compiled as a stand alone dll and called from an application. There are two stages of execution for the plugin: 1. Set up as part of a winforms application, then 2) execution as part of a windows service. In generating the setup information I specify a list of types of "Email Processor" class to use, where EmailProcessor is an abstract class and each type of email processor extends that abstract class to create in instance class. In saving the settings, the list of EmailProcessors was to be saved using XmlSerialisation (this is functionality of the parent application and not my plugin), which throws an error since the type of the EmailProcessor is dynamic. I can't implement any sort of custom XmlSerialisation so I have had to make the abstract EmailProcessor class into a real (non-abstract) class and then throw a NotImplementedException from each of its methods. This has obviously broken the basic inheritance model slightly - not so much as to be truly irritating but enough to make me think there was probably a more correct way of approaching the issue. Can anyone suggest to me what I should have done to allow EmailProcessors to maintain their inheritance model but overcome the issues I had with getting round the XmlSerialisation of dynamic types that I had no control over? Any thoughts greatly appreciated. Cheers, Adam
I might not get your complete plugin design... however I'll try an answer. How about a plugin impements an interface (e.g. pure abstract class in C++), one method could be
OnSerialise(HFILE hFile)
. Whenever the application needs to serialise data it will find the corresponding plugin and request it to serialise its data by calling pPlugin->OnSerialise(). The file handle is just an example in case you want that multiple plugins write into the same file. Here an example plugin interface, the first two methods are generic:class IPluginInterface { public: virtual int GetVersionNumber() const = 0; virtual void DeleteThis() const = 0; virtual bool OnSerialise(HFILE hFile) = 0; virtual bool OnDoStuff(int nEvent) = 0; };
-
Look at the article I posted on creating a plug-in architecture at http://www.codeproject.com/useritems/TaskPlugin.asp. There is a good use of it in the Task Scheduling application that I wrote at http://www.codeproject.com/useritems/Guadagno_task_scheduler.asp Hope this helps, Joseph Guadagno http://www.josephguadagno.net
Hi Joseph, Thanks very much for the response, but unfortunately (as was mentioned in my original request but perhaps could have been made clearer) the plugin architecture is already in place as part of an application that is already live on a number of systems. The only reason for mentioning the plugin architecture is actually to define the constraint the my settings must be stored using XmlSerialisation, which is what causes my problem in implementing a proper inheritance model. Thanks for your help, I appreciate you taking the time to respond.
-
I might not get your complete plugin design... however I'll try an answer. How about a plugin impements an interface (e.g. pure abstract class in C++), one method could be
OnSerialise(HFILE hFile)
. Whenever the application needs to serialise data it will find the corresponding plugin and request it to serialise its data by calling pPlugin->OnSerialise(). The file handle is just an example in case you want that multiple plugins write into the same file. Here an example plugin interface, the first two methods are generic:class IPluginInterface { public: virtual int GetVersionNumber() const = 0; virtual void DeleteThis() const = 0; virtual bool OnSerialise(HFILE hFile) = 0; virtual bool OnDoStuff(int nEvent) = 0; };
I did consider the use of interfaces to get round the problem, but unfortunately XmlSerialisation will still stumble on the main issue that I'm trying to store a list of EmailProcessors that would all have different types. The only way I came upon to get round this was to cast down to an actual instance of the parent type to store my setting and use a string within the parent type to allow me to cast back up to the appropriate child type after serialisation once the plugin is running. Is there a more correct solution or is this the only way round the dynamic typing issue caused by an XmlSerialisation process that I can't modify? Thanks very much for taking the time to respond - it is appreciated. Cheers, Adam
-
I did consider the use of interfaces to get round the problem, but unfortunately XmlSerialisation will still stumble on the main issue that I'm trying to store a list of EmailProcessors that would all have different types. The only way I came upon to get round this was to cast down to an actual instance of the parent type to store my setting and use a string within the parent type to allow me to cast back up to the appropriate child type after serialisation once the plugin is running. Is there a more correct solution or is this the only way round the dynamic typing issue caused by an XmlSerialisation process that I can't modify? Thanks very much for taking the time to respond - it is appreciated. Cheers, Adam
NamelessParanoia wrote:
main issue that I'm trying to store a list of EmailProcessors that would all have different types.
I think the solution could be using polymorphism in your design. I understand from your description that your serialiser needs to get the appropriate data from each EmailProcessor (each processor could be internally handle a different type). In C++ language I would suggest to derive EmailProcessor from an interface that has a pure virtual method such as
virtual void GetEmailData(buffer) = 0
, in different EmailProcessors you would specialise this method differently. Now, the serialiser can collect data from any EmailProcessor in (step one), then convert the collected data into a valid XML tree (step two). Hope it helps, Mark