Search code examples
asp.net-mvcplugins.net-4.5mef

ASP.NET MVC 5 Plugin


Perdon me, this is not any problem, rather is asking help from you.

I am completely new to pluggable application. I've not even think it before.

Currently I'm working in an SMS application which might have different gateways to send sms.

Among the gateways, right gateway is selected dynamically base on some criteria.

Different gateways require different url and data to send an SMS. i.e. -

 //This is for one gateway
 xyz.com/SendTextMessage?Username=XX&Password=XX&From=XX&To=XX&Message=##

 //This is for one gateway
 abc.com?IN_MSG_ID=XX&MOBILENO=XX&BODY=XX&ORIGIN_PORT=XX

For example, I need a plugin which is able to send sms -

void SendMessage()
{
     //Send via abc
}

There may be another plugin which can send sms-

void SendMessage()
{
     //Send via xyz
}

I can't figure out how I can prepare plugin for gateway without modifying the source code of main application.

May I have an idea from you?


Solution

  • Please refer to some documentation about Factory Pattern. Here is one - https://www.tutorialspoint.com/design_pattern/factory_pattern.htm

    Have an IMessageSender interface, which has a method SendMessage(), which takes a MessageObject parameter. MessageObject should have all the relevant details for sending the message. (From, To, Body etc)

    Now, you can have different implementations of IMessageSender interface, each using its own gatway and other details.

    ABCMessageSender : IMessageSender
    {
       void SendMessage(MessageObject messageObject)
       {
          //Send via abc
       }
    }
    
    XYZMessageSender : IMessageSender
    {
       void SendMessage(MessageObject messageObject)
       {
          //Send via xyz
       }
    }
    

    Now, you create a factory interface and a factory class

    public interface IMessageSenderFactory 
    {
        IMessageSender getMessageSender(MessageObject messageObject);
    }
    

    and then have an implementation for that interface

    public class MessageSenderFactory : IMessageSenderFactory  {
    
       //use getMessageSender method to get object of type MessageSender 
       public IMessageSender getMessageSender(MessageObject messageObject){
    
      if(messageObject == null){
         return null;
      }     
      if(messageObject.From.equalsIgnoreCase("Some condition")){
         return new ABCMessageSender();
    
      } else if(messageObject.Rate.equalsIgnoreCase("Some other condition")){
         return new XYZMessageSender();
    
      } //else if(some other condition){
         //return some other message sender
      //}
    
      return null;
    }
    }
    

    In the end, use the factory method above to get the appropriate instance of IMessageSender and invoke SendMessage() on it. If you use any of the dependency injection patterns, you can inject IMessageSenderFactory into your controller (or any other consuming class) and use it from there.