Help to abstract dependency?

Started by
4 comments, last by DareDeveloper 10 years, 8 months ago
I have a requirement where the the user needs to configure how they would like to get alerted when an error happens. The options they have are the following:
1.) Create an event in the event log
2.) Send an email to an email specified from the user interface
The classes i am using currently use the following interface

    interface INotificationSender
    {
       virtual void SendMessage(string message);
    }
my interface is going to be implemented by the following 2 concrete classes

    class EmailerNotificationSender: public INotificationSender
    {
       string m_EmailAddress;
    
       public EmailerNotificationSender(string emailAddress)
       {
           m_EmailAddress = emailAddress;
       }
       public virtual void SendMessage(string Message)
       {
          // Send Message to email specified in member variable
       }
    } 
    
    
    class EventLogNotificationSender: public INotificationSender
    {
       public virtual void SendMessage(string Message)
       {
          // Log message in event log using
       }
      
    }
My current interface code looks like the following

    public class MyUserinterfaceWindow
    {
        private INotificationSender m_NotificationSender; // concrete type depends on user interface selection!
    
        public void Button_Click(...)
        {
           if (emailSelected)
           {
               m_NotificationSender = new EmailerNotificationSender(textbox.email)
               return;
           }
            m_NotificationSender = new EventLogNotificationSender();
        }
    
        public void SendAlert()
        {
            m_NotificationSender.SendMessaged("SOMETHING BAD HAPPENED");
        }
    }
**Summary/Question:**
How do i remove the presence of concrete types being instantiated( for example EventLogNotificationSender and EmailerNotificationSender )
**NOTE:** EventLogNotificationSender requires no parameters in it's concrete constructor while EmailNotificationSender's concrete constructor takes a string parameter!
Advertisement
That's rather simple actually. Make a delegate to replace the "new xxx" and simply check if for true before calling it. Add a call or property to set the delegate (say: notificationSystem.SetSender( => new EmailerNotificationSender() );) and then the library remains oblivious to the transport mechanism. Of course you could use += like most delegates and the caller could attach multiple sources and it would just work. smile.png

That's rather simple actually. Make a delegate to replace the "new xxx" and simply check if for true before calling it. Add a call or property to set the delegate (say: notificationSystem.SetSender( => new EmailerNotificationSender() );) and then the library remains oblivious to the transport mechanism. Of course you could use += like most delegates and the caller could attach multiple sources and it would just work. smile.png

Sorry but i don't understand what you mean. The UI is still calling new on the concrete type. Could u provide a more "codeish" example that might help me understand easier

I assume you read about inversion of control or dependency injection somewhere.

Guess what you want to do is write a provider (like with Google's Guice in Java), "inject" an INotificationSender and let the IoC framework use the settings file to figure out the correct implementation!?

There are some libraries that make IoC in C++ possible.

I really enjoyed working that way in Java ... writing three providers and using different annotations when I want to inject a concrete implementation.

I don't think the way the C++ ones work is very pretty. In C++ you might want to find a different way.

You can search for "C++ and IoC" and follow the links. Many libraries have examples of how they are used.

http://code.google.com/p/hypodermic/ - seems too simple for what you have in mind, but maybe it can be used somehow

http://code.google.com/p/pococapsule/ - might be something ... have not really done much research yet

There are articles about manually writing code with DI in mind, like this one:

http://adam.younglogic.com/2008/07/dependency-injection-in-c/

The code there seems like something I could get used to ... and there is a link to an example implementation near the end of the article.

Another article that clarifies quite a few words and concepts pretty well (but careful ... it is C# / .NET):

http://www.codeproject.com/Articles/380748/Inversion-of-Control-Overview-with-Examples

Given enough eyeballs, all mysteries are shallow.

MeAndVR

It seems almost as good as it can be: you are simply creating the right type of notifier after the user chooses which one he wants. Further sophistication doesn't seen warranted.

How do you ensure SendAlert is called after Button_Click? I would use a default notifier, maybe a no-op third implementation, to ensure the window always has a valid notifier.

Omae Wa Mou Shindeiru

I wouldn't say that. If you manage to avoid having the game settings read and used all over the place the effort is justified IMO.

If you put that logic in the providers, it keeps the code using the dependency injection a lot cleaner and you'll know where to look for the evaluation of settings/properties.

Once a class depends on lots of modules and services and there are many ways to configure what they do the code can get pretty ugly.

Given enough eyeballs, all mysteries are shallow.

MeAndVR

This topic is closed to new replies.

Advertisement