Click here to Skip to main content
15,893,904 members
Articles / Programming Languages / C#

A Flexible Plugin System

Rate me:
Please Sign up or sign in to vote.
4.98/5 (25 votes)
3 Sep 2008LGPL34 min read 131.5K   1.8K   163  
A generic plugin system used to load and manage plugins
using System;
using System.Collections.Generic;

namespace Fadd.Commands
{
    /// <summary>
    /// Invokes all handlers for a command.
    /// </summary>
    internal class AsyncQueueItem
    {
        private readonly object _source;
        private readonly Command _command;
        private readonly Queue<CommandHandler> _handlers = new Queue<CommandHandler>();
        private readonly CommandManager _cmdMgr;
        private CommandHandler _current;
        private readonly AsyncQueueItemResult _result;
        private readonly AsyncCallback _callback;

        /// <summary>
        /// Initializes a new instance of the <see cref="AsyncQueueItem"/> class.
        /// </summary>
        /// <param name="source">used as "source" in the command event delegate.</param>
        /// <param name="cmd">command being executed.</param>
        /// <param name="cmdMgr">Used to check if propagation may be cancelled.</param>
        /// <param name="callBack">callback when command have been executed..</param>
        /// <param name="result">async result.</param>
        public AsyncQueueItem(object source, Command cmd, CommandManager cmdMgr, AsyncCallback callBack, AsyncQueueItemResult result)
        {
            _source = source;
            _command = cmd;
            _cmdMgr = cmdMgr;
            _result = result;
            _callback = callBack;
        }

        public void Add(CommandHandler handler)
        {
            _handlers.Enqueue(handler);
        }

        public bool BeginInvoke()
        {
            if (_handlers.Count == 0)
                return false;

            _current = _handlers.Dequeue();
            _current.BeginInvoke(_source, _result.Args, OnEndInvoke, null);
            return true;
        }

        private void OnEndInvoke(IAsyncResult ar)
        {
            if (_current.EndInvoke(ar))
                _command.SetHandled(true);

            if (_result.Args.CancelPropagation
                && _cmdMgr.InvokePropagationCancelled(_command, _current))
            {
                TriggerCompleted();
                return;
            }

            // Completed if list is empty
            if (!BeginInvoke())
                TriggerCompleted();
        }

        private void TriggerCompleted()
        {
            // Check if the unhandled event handles the command
            if (!_command.IsHandled)
                _cmdMgr.TriggerUnhandled(_command);

            _result.ToggleCompleted();
            if (_callback != null)
                _callback(_result);
                
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Founder 1TCompany AB
Sweden Sweden

Comments and Discussions