Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to override SetupStream on SocketInitiatorThread #527

Open
fabiomarreco opened this issue Jun 6, 2019 · 0 comments
Open

Unable to override SetupStream on SocketInitiatorThread #527

fabiomarreco opened this issue Jun 6, 2019 · 0 comments

Comments

@fabiomarreco
Copy link

fabiomarreco commented Jun 6, 2019

I have a data provider which needs some customization on the network stream (it requires to be decompressed).

Currently, the class SocketInitiatorThread has a method protected virtual SetupStream() with the comment:

/// <summary>
/// Setup/Connect to the other party.
/// Override this in order to setup other types of streams with other settings
/// </summary>
/// <returns>Stream representing the (network)connection to the other party</returns>

So this is clearly the place I should override and add the customization.

My problem is that this class is created on SocketInitiator.DoConnect, with this implementation:

protected override void DoConnect(SessionID sessionID, Dictionary settings)
{
    Session session = null;

    try
    {
        session = Session.LookupSession(sessionID);
        if (!session.IsSessionTime)
            return;

        IPEndPoint socketEndPoint = GetNextSocketEndPoint(sessionID, settings);
        SetPending(sessionID);
        session.Log.OnEvent("Connecting to " + socketEndPoint.Address + " on port " + socketEndPoint.Port);

        //Setup socket settings based on current section
        var socketSettings = socketSettings_.Clone();
        socketSettings.Configure(settings);

        // Create a Ssl-SocketInitiatorThread if a certificate is given
        SocketInitiatorThread t = new SocketInitiatorThread(this, session, socketEndPoint, socketSettings);                
        t.Start();
        AddThread(t);

    }
    catch (System.Exception e)
    {
        if (null != session)
            session.Log.OnEvent(e.Message);
    }
}

So, in order to inherit from SocketInitiatorThread, and override SetupStream, I have to also inherit from SocketInitiator and override DoConnect.

Unfortunatly, many methods used inside DoConnect are private (like GetNextSocketEndPoint, AddThread, etc.). And I´ll end up having to duplicate the whole class.

I propose either:
(1) Extract the line which creates the SocketInitiatorThread to a virtual method

   public virtual CreateSocketInitiatorThread(Session session, IPEndPoint socketEndPoint, SocketSettings socketSettings)
 { 
     return new SocketInitiatorThread(this, session, socketEndPoint, socketSettings);
} 

or
(2) Inject a factory (ISocketInitiatorThreadFactory) into SocketInitiator, such that:

 public interface ISocketInitiatorThreadFactory
    {
        SocketInitiatorThread Create(Transport.SocketInitiator initiator, Session session, IPEndPoint socketEndPoint, SocketSettings socketSettings);
    }

    class DefaultSocketInitiatorThreadFactory : ISocketInitiatorThreadFactory
    {
        public SocketInitiatorThread Create(SocketInitiator initiator, Session session, IPEndPoint socketEndPoint, SocketSettings socketSettings)
            => new SocketInitiatorThread(initiator, session, socketEndPoint, socketSettings);
    }

And then create a new constructor receiving the factory. (the other constructors will use the default factory).

I much rather the second approach since the 1st one can lead to violating LSP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant