Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define events and properties in a decorator

I defined an interface which has an event and a property defined as follows.

public interface IMyInterface
{
    event EventHandler SomeEvent;
    string GetName();
    string IpAddress { get; set; }
}

I then created a class and using it, every thing works fine.

Now I want to extend this class using a decorator. I am not sure how to handle the event. For the property I think I am clear, just want confirmation.

I defined the decorator class as follows.

public class LoggerDecorator : IMyInterface
{
    private readonly IMyInterface _MyInterface;
    private readonly ILog _MyLog;
    public LoggerDecorator(IMyInterface myInterface, ILog myLog)
    {
        if (myInterface == null)
            throw new ArgumentNullException("IMyInterface is null");
        _MyInterface = myInterface;

        if (myLog == null)
            throw new ArgumentNullException("ILog instance is null");
        _MyLog = myLog;

    }

    public string GetName()
    {
        // If needed I can use log here
        _MyLog.Info("GetName method is called.");
        return _MyInterface.GetName();
    }

    // Is this the way to set properties?
    public string IpAddress
    {
        get
        {
            return _MyInterface.IpAddress;
        }

        set
        {
            // If needed I can use log here
            _MyLog.Info("IpAddress is set.");
            _MyInterface.IpAddress = value;
        }
    }


    // But How to handle this evetn?? Please help. I am not clear about this.
    public event EventHandler SomeEvent;

}
like image 462
VivekDev Avatar asked Oct 22 '25 06:10

VivekDev


2 Answers

You can forward the subscription and unsubscription of the event to the element being decorated using add and remove. That way, if you subscribe to LoggerDecorator.SomeEvent, you actually subscribe to the inner IMyInterface.SomeEvent.

In your case, it should look like this:

public class LoggerDecorator : IMyInterface
{
    (...)

    public event EventHandler SomeEvent
    {
        add => _MyInterface.SomeEvent += value;
        remove => _MyInterface.SomeEvent -= value;
    }
}
like image 184
Batesias Avatar answered Oct 23 '25 19:10

Batesias


Ok, I think I got the answer.

The following goes in the ctor.

        _MyInterface.SomeEvent += _MyInterface_SomeEvent;

and the event handler method will be as follows.

    private void _MyInterface_SomeEvent(object sender, EventArgs e)
    {
        var someEvent = SomeEvent;
        if (someEvent != null)
        {
            someEvent(this, e);
        }
    }

The full implementation would be as follows.

public class LoggerDecorator : IMyInterface
{
    private readonly IMyInterface _MyInterface;
    private readonly ILog _MyLog;
    public LoggerDecorator(IMyInterface myInterface, ILog myLog)
    {
        if (myInterface == null)
            throw new ArgumentNullException("IMyInterface is null");
        _MyInterface = myInterface;

        if (myLog == null)
            throw new ArgumentNullException("ILog instance is null");
        _MyLog = myLog;

        // This is change 1.
        _MyInterface.SomeEvent += _MyInterface_SomeEvent;
    }

    // This is change 2
    private void _MyInterface_SomeEvent(object sender, EventArgs e)
    {
        var someEvent = SomeEvent;
        if (someEvent != null)
        {
            someEvent(this, e);
        }
    }

    public string GetName()
    {
        // If needed I can use log here
        _MyLog.Info("GetName method is called.");
        return _MyInterface.GetName();
    }

    // Is this the way to set properties?
    public string IpAddress
    {
        get
        {
            return _MyInterface.IpAddress;
        }

        set
        {
            // If needed I can use log here
            _MyLog.Info("IpAddress is set.");
            _MyInterface.IpAddress = value;
        }
    }


    public event EventHandler SomeEvent;

}
like image 33
VivekDev Avatar answered Oct 23 '25 20:10

VivekDev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!