How to mock events with internal constructors - c#

I have a service responsible for subscribing to EWS for new mail notification. I've created an interface for the service in order to mock it and test a dummy implementation. However, I'm running into a wall whenever I try to manually tell what my events are supposed to do.
Here is my concrete implementation.
public interface IExchangeService
{
void Subscribe();
}
public class ExchangeServiceSubscriber : IExchangeService
{
private readonly ExchangeService _exchangeService;
private readonly IConsumer<IEmail> _consumer;
public ExchangeServiceSubscriber(
ExchangeService exchangeService,
IConsumer<IEmail> consumer)
{
_exchangeService = exchangeService;
_consumer = consumer;
}
public void Subscribe()
{
// code to subscribe
streamingConnection.OnNotificationEvent += OnEvent;
streamingConnection.Open();
}
public void OnEvent(object sender, NotificationEventArgs args)
{
foreach (NotificationEvent triggeredEvent in args.Events)
{
if (triggeredEvent is ItemEvent)
{
var propertySet = new PropertySet(ItemSchema.UniqueBody, ItemSchema.Attachments)
{
RequestedBodyType = BodyType.Text
};
EmailMessage email = EmailMessage.Bind(args.Subscription.Service,
((ItemEvent)triggeredEvent).ItemId, propertySet);
_consumer.Consume(new ExchangeEmail { Body = email.UniqueBody });
}
}
}
}
And unfortunatly, almost every class in EWS is either sealed or has an internal constructor which really limits how I decouple them, it seems. I've attempted to set the expectation for NotificationEventArgs (for example) but it uses an internal constructor.
Here is some ideas I've been fiddling with. You can read about mocking events here.
mock.Setup(x => x.OnEvent(new object(), new NotificationEventArgs()));
Issue with that is NotificationEventArgs uses an internal constructor.
I could see getting this working with some sort of wrapper but I'm not exactly sure what it would look like. One of the big problems is the way EWS is made pretty much prevents anyone from manually injecting dependencies. I'm essentially trying to test that whenever event OnEvent fires that the email will actually get consumed. Also, while I would like to test this functionality I'm not sure it's worth fighting EWS every step of the way.

Let's first see, what you can't do:
You can't subclass NotificationEventArgs because the ctor is internal.
You can't create an instance directly for the same reason.
So basically, you can't create an instance of this class using the "normal way". I assume you already checked for a factory method or class?
This leaves us with only one option: Instantiate the class using reflection, e.g. with the help of the Activator.CreateInstance method: Unit testing exception handling for third party exceptions with internal constructors, like so:
mock.Setup(x => x.OnEvent(new object(),
Activator.CreateInstance(typeof(NotificationEventArgs),
BindingFlags.NonPublic | BindingFlags.Instance,
null,
null,
null))
);

Related

Swapping out logging action on reused instance based on calling instance

I have a class instance (Eli) which is used in multiple contexts, and which needs to log messages, independent of (but correctly in each) context:
public class Eli
{
void LogMessage(string msg)
{
///what to do here?
}
public void GrillTheCat()
{
LogMessage("I deed it";)
}
}
public class EliWrapper
{
Eli _eli;
Action<string> _logAction;
public EliWrapper(Eli eli, Action<string> logAction)
{
_eli = eli;
_logAction = logAction;
}
public void GrillTheCat()
{
_eli.GrillTheCat(); //I want LogMessage in Eli to invoke the _logAction of this calling instance
}
}
var eli = new Eli();
var wrapper1 = new EliWrapper(eli, msg => Console.WriteLine(msg));
var wrapper2 = new EliWrapper(eli, msg => File.AppendAllText(msg + "\n"));
I realize I could pass in the logger to the GrillTheCat function, but in my real situation, Eli has >10 functions and I don't want to clutter up all of the function signatures just for the sake of logging.
I also realize I could define a LogAction property on Eli, then have the wrappers assign their _logAction value to that property prior to invoking Eli's function, but again I have many functions and it would be somewhat tedious to wrap each one.
What I'm hoping for is a reflection-based solution where Eli's LogMessage function just steps up a couple layers of the call stack, and accesses the wrapper instance's _logAction directly.
What I'm hoping for is a reflection-based solution where Eli's LogMessage function just steps up a couple layers of the call stack, and accesses the wrapper instance's _logAction directly.
I wasn't able to find any reasonable way to access instances outside the current executing method without you heavily modifying signatures(you stated you didn't want to do).
Although I generally would not recommend what you're trying to do because of the tight coupling and general lack of extensibility and intuitiveness - However, I figured out a solution that almost fits the bill.
It is not possible, at least from what I was able to research, to access instance data from calling members. Which is to say you can't walk back up the stack and access instanced variables or objects all will-nilly, unless you explicitly capture and pass them down the stack as you're - err.. um "stacking"?.
The way we work around this is simply by declaring your _logAction as a static member. That way we don't need to access the instance you have of EliWrapper.
What this doesn't do for you is allow you to have multiple EliWrappers with different _logAction's becuase they're static.
Unfortunately without access to the individual instance(which you can't get from the stack - there's no way for Eli to know what EliWrapper wants to do without at least some of the modifications you explicitly wanted to avoid(In my opinion).
Where do we go from here?
Consider
Consider Modifying Eli so it can be used as a base-class that has different versions that log things differently.
Consider Modifying Eli to implement overrides that accept a Action<string> as a override for it's default logging.
Alternatively, but not recommended
Pass the instance of the caller to Eli so it can access instanced(non-static) members on EliWrapper so you don't need to make _logAction static(this would be a simple modification to the code i have provided to you, but would require changing all of Eli's signatures to accommodate object caller.
Store instances of EliWrapper somewhere you can access without instance, such as a static class, where you can access their instance data using reflection without explicitly passing their instances to Eli
Here's the script to access the static field using the stack
public class Eli
{
private readonly Action<string> DefaultLogger = (s) => Console.WriteLine(s);
void LogMessage(string msg)
{
// get the stack so we can get advanced information about
// who called us (CallerMemberNameAttribute was another alternative, but would incur more complex code)
StackTrace stack = new(false);
// step 2 frames up(or however many to get out of Eli and back to the 'caller'
var caller = stack.GetFrame(2)?.GetMethod()?.DeclaringType;
if (caller != null)
{
// check to see if the type that called GrillTheCat()
// has a static private field with the name '_logAction'
var possibleLoggerInCaller = caller.GetField("_logAction", BindingFlags.Static | BindingFlags.NonPublic);
if (possibleLoggerInCaller != null)
{
// get the static value of that field
var possibleLogger = possibleLoggerInCaller.GetValue(null);
// verify that the type of that logger is infact a Action<string>
// since that's what we use to log
if (possibleLogger is Action<string> logger)
{
// log the msg using the overriden logger instead of the default one
logger.Invoke(msg);
return;
}
}
}
// if we got here there wasn't a _logAction in the call stack at frame 2
// so give up and use our default logger
DefaultLogger.Invoke(msg);
}
public void GrillTheCat()
{
LogMessage("I deed it");
}
}
public class EliWrapper
{
Eli _eli;
private static Action<string> _logAction;
public EliWrapper(Eli eli, Action<string> logAction)
{
_eli = eli;
_logAction = logAction;
}
public void GrillTheCat()
{
_eli.GrillTheCat(); //I want LogMessage in Eli to invoke the _logAction of this calling instance
}
}
For my needs, I've gone with throwing exceptions. This procedurally does what I asked: only notifies the calling instance of the message, and requires no modification of function signatures.
Consider implementing a decorator for Eli that implements logging. Here is a rudimentary example that demonstrates this:
// If you haven't already: define an interface for Eli
public interface IEli
{
// Define all Eli's public members
}
// Let Eli implement IEli
public class Eli : IEli
{
...
}
With the existence of the new IEli interface, you can now implement a decorator:
public class LoggingEli : IEli
{
private readonly IEli decoratee;
private readonly Action<string> logAction;
public LoggingEli(IEli decoratee, Action<string> logAction)
{
this.decoratee = decoratee;
this.logAction = logAction;
}
// Implement all IEli members by calling the log action and forwarding
// the call to the decorated IEli instance:
public object SomeEliMethod(string param1, int param2)
{
this.logAction(nameof(SomeEliMethod) + " called for " + param1);
return this.decoratee.SomeEliMethod(param1, param2);
}
// Same for all other 9 IEli methods.
}
Using the new IEli interface and the LoggingEli decorator, you can now construct the following object graph:
var eli = new Eli();
var consoleEli = new LoggingEli(eli, msg => Console.WriteLine(msg));
var fileEli = new LoggingEli(eli, msg => File.AppendAllText(msg + "\n"));
Decorators have the advantage that you are able to add behavior to a class without having to change the original class. Downside is that it is only possible to add behavior at the start or end of the original method, and the behavior only has access to all the parameters going in and out of the called method. In your case, you can't log halfway the method, and can't log anything information that is kept internal to Eli.
In case you need to log halfway or use information that is internal to Eli, you will need to inject the logger into Eli's constructor.

Pass object into method without adding argument to method?

I have a simple interface called IEvent and it just contains this one method:
void Execute();
I have several derived classes from this interface and one of them needs access to an object that the caller of the method owns. The object is used in this fashion:
using (MyObject object = new MyObject(this.MessageService)
{
foreach (IEvent myEvent in eventList)
{
myEvent.Execute(); // <--- I need to pass object without adding argument here if possible?
}
}
I would add the object as a field in the derived class that needs access to it, but by the time I get to this part of the code, the IEvent objects are already constructed and running on a background thread. Currently, the only way I can think of is to add a setter in the IEvent interface for this object, but then I am exposing a field that most derived classes won't care about and doesn't seem like a clean solution.
I would add it as an argument to Execute(), but the problem is that the object belongs to an assembly that the assembly that contains IEvent doesn't know about (and don't want it to know about) and again 99% of the events don't care about this object anyway. Is there a better way to accomplish what I am trying to do here?
"If a class that implements IEvent does not/can not implement all the methods specified by IEvent the same way as they are declared in IEvent, that class should not implement IEvent in the first place." - Sweeper
So there's probably something wrong with your design of the whole program. I think you better revise your design a little bit and change some relationships between the classes and interfaces.
If you don't want to do that, there is another (not recommended) way to solve this problem.
Suppose your method caller is of type MethodCaller. You just change the declaration of Execute in the interface to this:
void Execute(MethodCaller obj = null);
And all the classes that implement IEvent can ignore the parameter except the class you mentioned in your question.
I'm going to piggyback on Jon Skeet's amazing knowledge of C#, .NET, CLR, IL and everything that surrounds any of those topics. You can't get to the instance of the calling object and especially the local varaible in the calling method. You can get its type, you can get the calling method through StackTrace, for example (StackTrace.GetFrames()), but none of those are going to do you any good in this situation. What you're trying to accomplish would require some heavy dive into the debugging API. As far as walking the stack, here's a quick sample I created to try see if I can figure something out for you (I made assumptions in regards to how your program is structured... obviously it's not a one to one sample):
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SampleApp
{
class Program
{
static void Main(string[] args)
{
var eventList = new List<IEvent> { new SomeClass() };
using (MyObject obj = new MyObject(new MessageService()))
{
foreach (IEvent myEvent in eventList)
{
myEvent.Execute();
}
}
}
}
public interface IEvent
{
void Execute();
}
public class SomeClass : IEvent
{
public void Execute()
{
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
var callingMethod = stackFrames[1].GetMethod();
var callingType = callingMethod.DeclaringType;
}
}
public class MyObject : IDisposable
{
public MessageService Service { get; }
public MyObject(MessageService service)
{
Service = service;
}
public void Dispose()
{
Service.Stop();
}
}
public class MessageService
{
public void Start() { }
public void Stop() { }
}
}
I like your question, because it presents an interesting and an unusual situation, but I'm afraid that you won't be able to accomplish your task without going outside of conventional routines that C# has in its arsenal. You may be able to pull something off with unmanaged code, but that's a different topic altogether.
However, aside from it being an interesting question... look at what you're trying to do. You have MyObject, which obviously implements IDisposable and will call Dispose() at the end of that using statement, and you're trying to grab its reference from a different assembly. I don't think this is a good idea.
I suggest revisiting your design and make use of things such as an optional parameter. May not be the "perfect" solution for your situation, as you'll pass it to every Execute in that foreach loop, but it's better than jumping through a thousand fiery hoops of debug API's.

TDD can force the creation of "fake" dependencies

I'm using a boilerplate implementation of Model-View-Presenter in an ASP.NET WebForms application. My View has two events of consequence, one that signals that the user has filled out enough fields on the domain model to initiate a duplication check, and the other is a regular Save event. My pseudo code looks like this:
public class ItemNewPresenter : PresenterBase<IItemNewView>
{
public IItemService Service { get; private set; }
public IItemNewView View { get; private set; }
public ItemNewPresenter(IItemService service, IItemNewView view)
{
Service = service;
View = view;
View.OnSave += DoItemSave;
View.OnItemIsDuplicateCheck+= DoItemIsDuplicateCheck;
}
private void DoItemIsDuplicateCheck(object sender, CheckItemDuplicateEventArgs e)
{
CheckForItemDuplication(e.Item);
}
private void CheckForItemDuplication(Item item){
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item), "This item already exists");
}
}
private void DoItemSave(object sender, SaveItemEventArgs e)
{
DoItemIsDuplicateCheck(this, e.ToItemDuplicateEventArgs());
Service.Save(e.Item);
}
}
Here's my test for ensuring that my presenter behaves properly when OnItemIsDuplicateCheck is raised from the view:
[Test]
public void presenter_checking_for_existing_item_should_call_redirect_if_found()
{
var service = new Mock<IItemService>();
var view = new Mock<IItemNewView>();
var presenter = new ItemNewPresenter (service.Object, view.Object);
var onCheckExistingHandler = view.CreateEventHandler <CheckItemDuplicateEventArgs>();
view.Object.OnExistingDenominatorCheck += onCheckExistingHandler;
var eventArgs = new CheckItemDuplicateEventArgs();
service.Setup(s => s.IsDuplicate(It.Is<CheckItemDuplicateEventArgs>(c => c.Equals(eventArgs)))).Returns(true);
onCheckExistingHandler.Raise(eventArgs);
view.Verify(v => v.RedirectWithNotification(It.IsAny<String>(), It.IsAny<string>()), Times.Once());
service.Verify();
}
For consistency, I would like to have the same duplicate check fired when the View raises the OnSave event. My question is around how I am supposed to write my test when one of the methods I want to verify (CheckForItemDuplication) is declared on the class under test. The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
[Test]
public void presenter_saving_item_should_check_for_dupe_and_save_if_not_one() {
//duplicate mocks/setups/asserts from duplicate check fixture
//additional mocks/setups/asserts to test save logic
}
I think TDD would suggest pulling this private method out into a separate class that collaborates with my Presenter and would be injected via DI. But adding another dependency to my Presenter for functionality that doesn't seem worthy of being a freestanding abstraction *and*represents an internal implementation detail of my Presenter seems...well...crazy. Am I way off base here? There must be some design pattern or refactoring I can apply that would avoid the need to turn a private method into a dependency.
What I have done sometimes, when confronted with this dilemma, is to extract the function, make an internal constructor with the object as argument, AND a public constructor without. The public ctor is forwarded to the internal with a new object such as:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
Thus, you can use the empty constructor from outside, and the other constructor for when you want to inject a stubbed argument for testpurposes. As long as the empty constructor only forwards the call without any logic of its own, you can still test it, like it has only one constructor.
I would go with testing the class as is by adding the duplicate setup code. Once that test is passing and you are confident all test cases are covered you can then refactor your test code to remove duplication.
You can move the dependencies (service and view) to private fields, then add a method to create the SUT:
private Mock<IItemService> _service;
private Mock<IItemNewView> _view;
private PresenterBase<IItemNewView> CreateSUT()
{
_service = new Mock<IItemService>();
_view = new Mock<IItemNewView>();
return new ItemNewPresenter (service.Object, view.Object);
}
(I think most people would prefer to initialize the Mock objects in the Setup method.)
Call the CreateSUT from your tests and now there is a little less duplication. Then you may want to add private method(s) for creating the event handler / raising the event as long as it is something that is being done the same or similar in more than one tests case.
Having this CreateSUT method cuts down on the amount of test code that is calling your constructor making it easier in the future if you were to add / remove / change dependencies. If you treat your test code like any other code and use the DRY principle when you see duplication it can result in more explicit, easier to read, maintainable test code. Dealing with very similar setup and test context is a common issue with unit testing and should not always change how the class being tested is/was designed.
I'll be interested if there are better answers, as I encounter this all the time.
The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
I'm not sure why you feel it makes the test less focused, but in your shoes I would do exactly what it sounds like you don't want to do--have duplicated setup code to test isolated cases for the SUT. You are testing the external behavior of the SUT with the test you supplied, which seems exactly right to me.
I am personally not a fan of exposing more than is necessary from a class and/or making behavior that should be the responsibility of the SUT into a dependency just to facilitate testing. The "natural boundry" of the class's responsibility should not be violated just because you want to test it.
It is easier to unit-test the calculation of the url than to unit-test that redirection has occured.
If i understood you corretly you want to test that the mvp-s CheckForItemDuplication() redirects to a certain url by raising
the view-mock-s OnItemIsDuplicateCheck event.
private void CheckForItemDuplication(Item item)
{
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item),
"This item already exists");
}
}
In my opinion you are doing to much.
What if you rewrite your code as
internal protected GetErrorUrlForItem(Item item)
{
if (Service.IsDuplicateItem(item))
{
return BuildItemUrl(item,
"This item already exists");
}
return null;
}
private void CheckForItemDuplication(Item item)
{
var result = GetErrorUrlForItem(item);
if (result != null)
{
View.RedirectWithNotification(result);
}
}
In the unittest just test the internal method GetErrorUrlForItem(). You have to use the InternalsVisibleTo attribute to allow accessing the internal method.

NUnit Mocking not working for Singleton Method

Bear with me, I'm new to NUnit. I come from the land of Rails, so some of this is new to me.
I have a line of code that looks like this:
var code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
I'm trying to mock it, like this (assume code is already initialized):
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
When I debug the test, getCodeByCodeNameAndType is returning null, instead of the expected code. What am I doing wrong?
NUnit version: 2.2.8
I'm sorry, but I've never used NUnit.Mocks - but I do have some experience with NMock and Moq [which, by the way, I highly recommend]. Typically, you use a mocking library to generate proxies for Interface definitions, and I presume NUnit.Mocks operates the same way.
Therefore, if you would like to mock your singleton, you will likely have to do the following,
a. Create an interface, say
// All methods you would like to mock from this class, should
// be members of this interface
public interface IWebSiteConfiguration
{
// Should match signature of method you are mocking
CodeType getCodeByCodeNameAndType (
string codeString,
CatalogType catalogType);
}
b. "Implement" interface
// You've already written the method, interface matches signature,
// should be as easy as slapping interface on class declaration
public class WebSiteConfiguration : IWebSiteConfiguration { }
c. Consume interface
alright, so step c. is where most of your work will be. Logically, if you are mocking your singleton, you are actually unit testing the consumer [which you have left out of your sample]. For c. simply add a parameter to the consumer's ctor, or add a publicly accessible property of Type 'IWebSiteConfiguration', and then internally, reference the instance member and invoke your methods against this new interface. Consider this,
was
public class MyClass
{
public MyClass () { }
public void DoSomething ()
{
// bad singleton! bad boy! static references are bad! you
// can't change them! convenient but bad!
code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType (
"some.string",
someCatalog)
}
}
becomes
public class MyClass
{
private readonly IWebSiteConfiguration _config = null;
// just so you don't break any other code, you can default
// to your static singleton on a default ctor
public MyClass () : this (WebSiteConfiguration.Instance) { }
// new constructor permits you to swap in any implementation
// including your mock!
public MyClass (IWebSiteConfiguration config)
{
_config = config;
}
public void DoSomething ()
{
// huzzah!
code = _config.getCodeByCodeNameAndType ("some.string", someCatalog)
}
}
In your unit test, create the mock, pass a reference of the mock to the consumer, and test the consumer.
[Test]
public void Test ()
{
IWebSiteConfiguration mockConfig = null;
// setup mock instance and expectation via
// NUnit.Mocks, NMock, or Moq
MyClass myClass = new MyClass (mockConfig);
myClass.DoSomething ();
// verify results
}
This also serves as a practical introduction to Dependency Injection [DI]. It's simply the practice of passing, or "injecting", references of services [eg your web site configuration class] to the consumer, rather than having the consumer invoke the service directly [eg via static singleton class].
Hope this helps :)
A DynamicMock creates a new object in-memory that represents the interface, or marshallable (inherits from MarshalByRef) class you want to mock.
Try this:
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
WebSiteConfiguration conf = (WebSiteConfiguration)_websiteConfigurationMock.MockInstance;
var x = conf.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
Note that the third line there will not work unless WebSiteConfiguration inherits from MarshalByRef.
What you typically do is mock an interface and get a new object that implements this interface, but behaves the way you've configured it to do, without having to go and make a concrete type for it, so I'm not entirely sure what you're doing is going to work unless you employ a better isolation framework, like TypeMock that can intercept calls to static methods/properties in existing objects.
Seems there is a kind of solution for this using reflection, or maybe I totally misunderstood this.
It is discussed here:
http://www.geekbeing.com/2010/05/23/how-to-unit-test-singleton-hack-in-c
Could it really works?
public class TestableSingleton : SingletonClass
{
public TestableSingleton ()
{
FieldInfo fieldInfo = typeof(SingletonClass)
.GetField("_instance",
BindingFlags.Static | BindingFlags.NonPublic);
fieldInfo.SetValue(Instance, this);
}
}
Project availabe on https://github.com/rbabreu/TestableSingleton
Actually I could not compile it on Visual Studio since the SingletonClass would have a private constructor. If someone get it to work would be great to avoid the overhead of adapter pattern.

What role do delegates play in dependency injection?

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");
}
}
}
}
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.
Going back to object oriented principles, one of the key features of an object is that it has behaviour and state. I could envision a scenario where a log handler might need to maintain some sort of state (logfilename, db connection, etc.), but there might also be an argument for a log handler not needing to concern itself with state.
If your dependency needs to manage state of its own, use a proper object (rather, an interface).
If your dependency has only behaviour and not state, then a delegate might be suitable, although some people might be more comfortable using a proper object (interface) anyway, as it might be easier to add state management to it later on if needed.
A benefit of delegates is that they're CRAZY simple to mock with lambda expressions :) (even though interfaces are pretty easy to mock, too)
Now of course any delegate can still just be some normal method on some normal object, and that method can totally have behaviour that affects the state of the object, and there are certainly valid reasons to do that, but you're approaching the point where it might make more sense just to take a dependency on the whole object, instead of just one of its methods.
Further down this path, injecting delegates can also be a way to apply Interface Segregation Principle, so you can make sure your system isn't dependent on things it doesn't use.
One further note about delegates...
There's almost never a good reason to define your own delegate type. Most of the use cases fit into the Func<> and Action<> C# types (and events, but that's another issue).
In your case, your MainApplication constructor should not take a Window1.LogHandler as a parameter, but instead just an Action<string>. Then you'd just call it with:
MainApplication app = new MainApplication(ConsoleLogHandler, new ToughSecurityManager());
or similar, since the ConsoleLogHandler method already fits the Action<string> signature.
And in your test, you'd just instanciate it with:
MainApplication app = new MainApplication(x => { /*Do nothing*/ }, new MySecurityManagerStub());
or even better:
int timesCalled;
MainApplication app = new MainApplication(x => { timesCalled++ }, new MySecurityManagerStub());
Then you can verify that MainApplication called the method exactly as many times as you intended.
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.

Categories