Накрутка сторонних компонент для использования в Windows


Я с помощью стороннего компонента коммерческих сервера слушать для SAP idoc-файлов. Я хочу запустить сервер внутри службы Windows и производитель рекомендует иметь отдельный метод для проверки сервера по тайм-ауты и перезапустить его в случае необходимости.

Я создал оболочку для серверного компонента и класса, чтобы периодически проверять на тайм-ауты, но я думаю, что это можно было бы сделать лучше. Конкретно я думаю, что есть много избыточности в обертке, и я интересно, если это все, что необходимо, а также что можно улучшить с точки зрения тестируемости?

Любые другие отзывы и замечания приветсвуются.

namespace IdocListener
{
    public interface IServer
    {
        bool IsRunning { get; }

        void Start();

        void Stop();

        event EventHandler<EventArgs> Started;

        event EventHandler<EventArgs> Stopped;

        event EventHandler<LoggedEventArgs> ServerMessage;

        event EventHandler<Exception> ServerException;
    }

    public class Server : IServer, IDisposable
    {
        bool isDisposed;

        public Server()
        {
            this.RfcServer = this.InitServer();

            this.RfcServerTimeoutChecker = new ServerTimeoutChecker(this);
        }

        RFCServer RfcServer { get; }

        ServerTimeoutChecker RfcServerTimeoutChecker { get; }

        public bool IsRunning
        {
            get { return this.RfcServer != null && this.RfcServer.IsRunning; }
        }

        /// <summary>
        /// Start the server
        /// </summary>
        public void Start()
        {
            if (!this.IsRunning)
            {
                this.RfcServer.Start();
            }
        }

        /// <summary>
        /// Stop the server
        /// </summary>
        public void Stop()
        {
            if (this.IsRunning)
            {
                this.RfcServer.Stop();
            }
        }

        public event EventHandler<EventArgs> Started;

        public event EventHandler<EventArgs> Stopped;

        public event EventHandler<LoggedEventArgs> ServerMessage;

        public event EventHandler<Exception> ServerException;

        RFCServer InitServer()
        {
            var rfcServer = new RFCServer
            {
                CanReceiveIdocs = true,
                Logging = true
            };

            rfcServer.Started += this.RfcServer_Started;
            rfcServer.Stopped += this.RfcServer_Stopped;
            rfcServer.Logged += this.RfcServer_Logged;
            rfcServer.InternalException += this.RfcServer_InternalException;
            rfcServer.IncomingIdoc += this.RfcServer_IncomingIdoc;

            return rfcServer;
        }

        // SERVER EVENTS

        void RfcServer_Started(object sender, EventArgs e)
        {
            this.Started?.Invoke(this, e);
        }

        void RfcServer_Stopped(object sender, EventArgs e)
        {
            this.Stopped?.Invoke(this, e);
        }

        void RfcServer_InternalException(RFCServer sender, Exception e)
        {
            string serverTypeName = this.RfcServer.GetType().Name;

            this.ServerException?.Invoke(this, new Exception($"The internal {serverTypeName} through an exception", e));
        }

        void RfcServer_Logged(object sender, LoggedEventArgs e)
        {
            this.ServerMessage?.Invoke(this, e);
        }

        void RfcServer_IncomingIdoc(RFCServer sender, Idoc idoc)
        {
            throw new NotImplementedException();
        }

        // IDISPOSABLE IMPLEMENTATION

        public void Dispose()
        {
            this.Dispose(true);

            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (this.isDisposed || !disposing)
            {
                return;
            }

            this.RfcServer?.Dispose();

            this.isDisposed = true;
        }
    }

    public class ServerTimeoutChecker
    {
        readonly IServer server;

        readonly Timer timeoutChecker;

        public ServerTimeoutChecker(IServer server)
        {
            if (server == null)
            {
                throw new ArgumentNullException(nameof(server));
            }

            this.server = server;
            this.server.Started += this.Server_Started;
            this.server.Stopped += this.Server_Stopped;

            this.timeoutChecker = new Timer(30000D)
            {
                AutoReset = true,
                Enabled = true,
            };

            this.timeoutChecker.Elapsed += this.TimeoutChecker_Elapsed;
        }

        void Server_Started(object sender, EventArgs e)
        {
            this.timeoutChecker.Start();
        }

        void Server_Stopped(object sender, EventArgs e)
        {
            this.timeoutChecker.Stop();
        }

        void TimeoutChecker_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (!this.server.IsRunning)
            {
                this.server.Start();
            }
        }
    }
}


98
1
задан 28 февраля 2018 в 09:02 Источник Поделиться
Комментарии