Sign in to follow this  
El OsO AntiGuo

Help to abstract dependency?

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Edited by DareDeveloper

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this