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.
Related
Is there a way to call a method to be executed before another method, like a trigger?
Something like an attribute that indicates the method to be executed, like this:
[OnBefore(MethodToBeExecutedBefore)]
public void MethodExecutedNormally()
{
//method code
}
I have a situation that I need to call a check method very often, and most of the time, they are before methods that take too long to execute.
There is no built in way to achieve this result, if you are using a dependency injection mechanism you can use the interception facilities if the DI framework supports this. (Ex: Unity, NInject)
If you want to go low level you can also use Reflection.Emit to create a derived class at runtime, that overrides methods with a particular attribute that invokes any extra functionality you want, but that is more difficult.
What you are talking about is called AOP or Aspect Oriented Programming.
There are no built-in options in C#. While Attributes exists, there is no mechanism to take any actions with them. You always need a piece of code that reads those attributes and then does something. Attributes themselves are only metadata and markers.
As far as external tools go, Postsharp is the de-facto standard AOP postcompiler for .NET, but it's not free (at least not for real use, there is a free version you may want to try, maybe it's enough for your use-case).
I think you should consider an event driven approach.
You could create an interface and some base classes to handle the event, then have your long running classes inherit from it. Subscribe to the event and handle accordingly:
public delegate void BeforeMethodExecutionHandler<TArgs>(ILongRunningWithEvents<TArgs> sender, TArgs args, string caller);
public interface ILongRunningWithEvents<TArgs>
{
event BeforeMethodExecutionHandler<TArgs> OnBeforeMethodExecution;
}
public class LongRunningClass<TArgs> : ILongRunningWithEvents<TArgs>
{
private BeforeMethodExecutionHandler<TArgs> _onBeforeMethodExecution;
public event BeforeMethodExecutionHandler<TArgs> OnBeforeMethodExecution
{
add { _onBeforeMethodExecution += value; }
remove { _onBeforeMethodExecution -= value; }
}
protected void RaiseOnBeforeMethodExecution(TArgs e, [CallerMemberName] string caller = null)
{
_onBeforeMethodExecution?.Invoke(this, e, caller);
}
}
public class ConcreteRunningClass : LongRunningClass<SampleArgs>
{
public void SomeLongRunningMethod()
{
RaiseOnBeforeMethodExecution(new SampleArgs("Starting!"));
//Code for the method here
}
}
public class SampleArgs
{
public SampleArgs(string message)
{
Message = message;
}
public string Message { get; private set; }
}
Sample usage:
public static void TestLongRunning()
{
ConcreteRunningClass concrete = new ConcreteRunningClass();
concrete.OnBeforeMethodExecution += Concrete_OnBeforeMethodExecution;
concrete.SomeLongRunningMethod();
}
private static void Concrete_OnBeforeMethodExecution(ILongRunningWithEvents<SampleArgs> sender, SampleArgs args, string caller)
{
Console.WriteLine("{0}: {1}", caller ?? "unknown", args.Message);
}
The message SomeLongRunningMethod: Starting! will be output before the long-running method executes.
You could add the caller name to the args. I whipped this out real quick to illustrate.
UPDATE: I see you added tags for ASP.NET MVC. The concept still applies to controllers as controllers are just classes.
I have an interface:
interface ISqlite
{
void insert();
void update();
void delete();
void select();
}
And custom service class:
class SqliteService
{
public SQLiteDatabase driver;
public SqliteService() {
SqliteConnection(new SQLiteDatabase());
}
public void SqliteConnection(SQLiteDatabase driver)
{
this.driver = driver;
}
public void select(ISqlite select) {
select.select();
}
public void insert(ISqlite insert) {
insert.insert();
}
public void delete(ISqlite delete)
{
delete.delete();
}
}
And last class Pacients that realizes ISqlite interface:
class Pacients: ISqlite
{
public List<ClientJson> pacients;
public Pacients() {
this.pacients = new List<ClientJson>();
}
public void add(ClientJson data) {
this.pacients.Add(data);
}
public void insert()
{
throw new NotImplementedException();
}
/* Others methos from interface */
}
I try to use my code like as:
/* Create instance of service class */
SqliteService serviceSqlite = new SqliteService();
/* Create instance of class */
Pacients pacient = new Pacients();
pacient.add(client);
serviceSqlite.insert(pacient);
As you can see above I send object pacient that realizes interface ISqlite to service. It means that will be called method insert from object pacient.
Problem is that I dont understand how to add data in this method using external class: SQLiteDatabase()? How to get access to this.driver in service class from object pacient?
Edit 1
I think I must move instance of connection new SQLiteDatabase() to db inside Pacients class is not it?
Generally speaking, I would favor a solution where the data objects themselves don't know anything about how they're stored, i.e. they have no knowledge of the class that communicates with the database. Many ORMs do just that.
Of course it might not be easy depending on the specifics of your situation... Try to examine what your methods on each object actually need; generally speaking they need the values of properties, and what column each property corresponds to, right? So any external class can do this if it knows these bits of information. You can specify the name of the column with a custom attribute on each property (and if the attribute isn't there, the column must have the same name as the property).
And again, this is the most basic thing that ORMs (Object Relational Mappers) do, and in addition they also manage more complicated things like relationships between objects/tables. I'm sure there are many ORMs that work with SqlLite. If you're OK with taking the time to learn the specifics of an ORM, that's what I would recommend using - although they're not silver bullets and will never satisfy all possible requirements, they are in my opinion perfect for automating the most common day to day things.
More to the point of the question, you can of course make it work like that if you pass the SQLiteDatabase object to the methods, or keep it in a private field and require it in the constructor or otherwise make sure that it's available when you need it; there's no other simple solution I can think of. And like you pointed out, it implies a certain degree of coupling.
You can change the signature of interface's methods to pass an SQLiteDatabase object.
interface ISqlite
{
void insert(SQLiteDatabase driver);
void update(SQLiteDatabase driver);
void delete(SQLiteDatabase driver);
void select(SQLiteDatabase driver);
}
Example call from the service:
public void insert(ISqlite insert)
{
insert.insert(driver);
}
I think you can figure out the rest by yourself.
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.
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))
);
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.