Stack Implementation using Managed Extensibility Framework

Hi Guys,

This time I made a small application to simulate a basic stack data structure. But to make things interesting I used Managed Extensibility Framework.

Before you Start,

1) Visual Studio with .NET Framework 4 or higher (Any Version)

Step One : The Solution

Create a console application project and a class library as shown in the image. Refer both the projects with System.ComponentModel.Composition. And add a reference to Console Application from the class library.

















Step Two : The Code

Paste the following code in the Program.cs file of MEFClient Project. 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFClient
{
    //Stack Implementation 
    [Export(typeof(IStack))]
    class MySimpleStack : IStack
    {
        [ImportMany]
        IEnumerable<Lazy<IOperation, IOperationData>> operations;
        int[] arr = { -1, -1, -1, -1, -1 };

        public String Process(String input)
        {
            string command;
            int val;


            int fn = FindSeperator(input); //finds the operator
            if (fn < 0) return "Could not parse command.";

            try
            {
                //separate out the operands
                command = input.Substring(0, fn);
                val = int.Parse(input.Substring(fn + 1));
            }
            catch
            {
                return "Could not parse command.";
            }



            foreach (Lazy<IOperation, IOperationData> i in operations)
            {
                if (i.Metadata.Command.Equals(command)) return i.Value.Manipulate(arr, val).ToString();
            }
            return "Operation Not Found!";
        }

        private int FindSeperator(String s)
        {

            for (int i = 0; i < s.Length; i++)
            {
                if (s[i] == ':') return i;
            }
            return -1;
        }


    }


    class Program
    {

        private CompositionContainer _container;

        [Import(typeof(IStack))]
        public IStack stack;


        private Program()
        {
            //An aggregate catalog that combines multiple catalogs
            var catalog = new AggregateCatalog();
            //Adds all the parts found in the same assembly as the Program class
            catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
            //Location of the directory of extensions
            catalog.Catalogs.Add(new DirectoryCatalog(@"C:\Users\Shahim\Documents\visual studio 2012\Projects\TestApplication\Extensions\bin\Debug"));


            //Create the CompositionContainer with the parts in the catalog
            _container = new CompositionContainer(catalog);

            //Fill the imports of this object
            try
            {
                this._container.ComposeParts(this);
            }
            catch (CompositionException compositionException)
            {
                Console.WriteLine(compositionException.ToString());
            }
        }

        static void Main(string[] args)
        {
            Program p = new Program(); //Composition is performed in the constructor
            String s;
            Console.WriteLine("Enter Command:");
            while (true)
            {
                s = Console.ReadLine();
                Console.WriteLine(p.stack.Process(s));
            }

        }
    }

    //Interface for the stack
    public interface IStack
    {
        String Process(String input);
    }

    //Interface for the operation 
    public interface IOperation
    {
        String Manipulate(int[] arr, int val);
    }

    // //Interface for the operation data 
    public interface IOperationData
    {
        String Command { get; }
    }

    //Push Implemenation
    [Export(typeof(IOperation))]
    [ExportMetadata("Command", "PUSH")]
    class Push : IOperation
    {
        public String Manipulate(int[] arr, int val)
        {
            bool pushed = false;

            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] == -1)
                {
                    arr[i] = val;
                    pushed = true;
                    break;
                }
            }

            return pushed ? "Value Pushed!" : "Value Was Not Pushed!";
        }
    }

}

Paste the following code in the ExtensionClass.cs file of Extensions Project. 

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Extensions
{
    //Pop Implementation
    [Export(typeof(MEFClient.IOperation))]
    [ExportMetadata("Command", "POP")]
    class Pop : MEFClient.IOperation
    {
        public String Manipulate(int[] arr, int val)
        {
            bool poped = false;
            int valuePoped = -1;

            for (int i = arr.Length - 1; i >= 0; i--)
            {
                if (arr[i] != -1)
                {
                    valuePoped = arr[i];
                    arr[i] = -1;
                    poped = true;

                    break;
                }
            }

            return valuePoped.ToString() + (poped ? " Value Poped!" : " Value Was Not Poped!");
        }
    }

    //Show Implementation
    [Export(typeof(MEFClient.IOperation))]
    [ExportMetadata("Command", "SHOW")]
    class Show : MEFClient.IOperation
    {
        public String Manipulate(int[] arr, int val)
        {
            string arrStr = string.Empty;

            for (int i = arr.Length - 1; i >= 0; i--)
            {
                arrStr += arr[i].ToString() + ",";
            }

            return arrStr.Substring(0, arrStr.Length - 1);
        }
    }

}

Step Three : Running the Program 


Comments

Popular posts from this blog

Secure .NET Core Api Server and Client

Security tips for hosting .NET Web Application on IIS

Simple API using Python, Flask and pyodbc