views:

140

answers:

2

In most examples of dependency injection, I see simple objects being injected, such as in the example below SecurityManager gets injected into MainApplication.

However, it would seem natural to inject delegates as well, as in the example below LogHandler gets injected into MainApplication.

Are delegates generally not used in dependency injection? What would be reasons for and against their use?

using System;
using System.Windows;
using System.Windows.Controls;

namespace TestSimpleDelegate82343
{
    public partial class Window1 : Window
    {
        public delegate void LogHandler(string message);

        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Gui_Lax_Click(object sender, RoutedEventArgs e)
        {
            MainApplication app = new MainApplication(new LogHandler(GuiLogHandler), new LaxSecurityManager());
        }

        private void Button_Console_Lax_Click(object sender, RoutedEventArgs e)
        {
            MainApplication app = new MainApplication(new LogHandler(ConsoleLogHandler), new LaxSecurityManager());
        }

        private void Button_Gui_Tough_Click(object sender, RoutedEventArgs e)
        {
            MainApplication app = new MainApplication(new LogHandler(GuiLogHandler), new ToughSecurityManager());
        }

        private void Button_Console_Tough_Click(object sender, RoutedEventArgs e)
        {
            MainApplication app = new MainApplication(new LogHandler(ConsoleLogHandler), new ToughSecurityManager());
        }

        public void GuiLogHandler(string message)
        {
            TextBlock tb = new TextBlock();
            tb.Text = "logging: " + message;
            TheContent.Children.Add(tb);
        }

        public void ConsoleLogHandler(string message)
        {
            Console.WriteLine("logging: " + message);
        }
    }

    public interface ISecurityManager
    {
        bool UserIsEntitled();
    }

    public class LaxSecurityManager : ISecurityManager
    {
        public bool UserIsEntitled()
        {
            return true;
        }
    }

    public class ToughSecurityManager : ISecurityManager
    {
        public bool UserIsEntitled()
        {
            return false;
        }
    }

    public class MainApplication
    {
        public MainApplication(Window1.LogHandler logHandler, ISecurityManager securityManager)
        {
            logHandler("test1");
            logHandler("test2");
            logHandler("test3");
            if (securityManager.UserIsEntitled())
            {
                logHandler("secret");
            }
        }
    }

}
+1  A: 

I know that MEF for example allows injecting delegates. However you can also make an ILog interface that has a Log method with the same signature as your delegate. I think it'll be much clearer to understand that the intend was to inject an implementation of an object capable of logging rather than a single log function.

Julien Lebosquain
+1  A: 

I occasionally use delegates as Anonymous Interfaces - also for DI.

One issue with this approach, however, is that it becomes a little bit more difficult to unit test that the correct Dependency was injected and used in a class, because a delegate instance isn't a type, and sometimes you'd simply just want to verify that a class uses the correct type of Strategy/Dependency.

Mark Seemann