Question

I have tried to raise event in cSharp to notify code change in my application in order to have tellDontAsk scenario.

I have simple class that implement from event class

public class SimpleTellDontAsk : ISomeEvent
{
    public void doSomething(string text, EventHandlerArgs args)
    {
        Console.WriteLine("Email this message {0}", text);
        //sending message with email
        args.IsDo = true;
        RaiseEvent(this, args);
    }

    public event EventHandler RaiseEvent;
}

I define my event class like below

public interface ISomeEvent
{
    event EventHandler RaiseEvent;
}

public class SomeEvent : ISomeEvent
{
    public event EventHandler RaiseEvent;
}

public class EventHandlerArgs : EventArgs
{
    public bool IsDo { get; set; }
}

I try to use my code with Nunit test

[TestFixture]
public class TestSimpleTellDontAsk
{
    [Test]
    public void Given_Text_When_doSomething_Then_ShouldPubliushArgs()
    {
        var tellDontAsk = new SimpleTellDontAsk();
        var senderEventHandlerArgs = new EventHandlerArgs();
        tellDontAsk.doSomething("test message", senderEventHandlerArgs);
        Assert.IsTrue(senderEventHandlerArgs.IsDo);
    }
}

When I run the test it comes up with null reference exception

System.NullReferenceException : Object reference not set to an instance of an object.

I believe something is missing but could not figure out , any idea ?

Was it helpful?

Solution

RaiseEvent isn't attached

 bool eventFired = false;

 var tellDontAsk = new SimpleTellDontAsk();
 tellDontAsk.RaiseEvent += (o, e) =>
            {
                if (e.IsDo)
                    eventFired = true;
            };
 tellDontAsk.doSomething("test message");
 Assert.IsTrue(eventFired);

Also if you want to use your own EventArgs "EventHandlerArgs" you should go for the Generic EventHandler.

The eventargs shouldnt be provided in the parameters to the method, they should be created when we need to raise the event.

public class SimpleTellDontAsk : ISomeEvent
{
    public void doSomething(string text)
    {
        Console.WriteLine("Email this message {0}", text);
        //sending message with email
        if (RaiseEvent != null) //Check if we have listeners
        {
            EventHandlerArgs args = new EventHandlerArgs();
            args.IsDo = true;
            RaiseEvent(this, args);
        }
    }
    public event EventHandler<EventHandlerArgs> RaiseEvent;
}

OTHER TIPS

RaiseEvent does not have handler attached , modified the code for attaching default handler , i am still not clear how it is implementing tell don't ask principle , you are just checking the IsDo property , what is the use of ISomeEvent?

public interface ISomeEvent
{
    event Action<ISomeEvent, EventHandlerArgs> RaiseEvent;
}

public class SomeEvent : ISomeEvent
{
    public event Action<ISomeEvent, EventHandlerArgs> RaiseEvent;
}
public class EventHandlerArgs : EventArgs
{
    public bool IsDo { get; set; }
}

public class SimpleTellDontAsk : ISomeEvent
{
    public SimpleTellDontAsk()
    {
        RaiseEvent = (s,e) => { };
    }                                
    public void doSomething(string text, EventHandlerArgs args)
    {
        Console.WriteLine("Email this message {0}", text);
        //sending message with email
        args.IsDo = true;
        RaiseEvent(this, args);
    }

    public event Action<ISomeEvent, EventHandlerArgs> RaiseEvent;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top