Blog Moved

April 5, 2011 Leave a comment

I have moved to hosted version of FunnelWeb. please go to http://www.loosechainsaw.com

Cheers.

Categories: Development

Basic Internal Dsl for Creating a Table Fluently :)

March 30, 2011 1 comment
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Html.Table.Dsl
{

    public static class ObjectHtmlExtensions
    {
        public static string GetValuesAsSeperatedTdTags(this object @object)
        {
            var type = @object.GetType();
            string output = String.Empty;
            foreach (var property in type.GetProperties())
            {
                output += "<td>" + property.GetGetMethod().Invoke(@object, null) + "</td>";
            }
            return output;
        }
    }

    public class TableModel
    {
        public string Caption { get; set; }
        public string Id { get; set; }
        public string Class { get; set; }
        public IList<TableHeader> Headers { get; set; }
        public IList<object> Objects { get; set; }

        public IEnumerable Rows
        {
            get { return Objects; }
        }

        public TableModel()
        {
            Caption = String.Empty;
            Headers = new List<TableHeader>();
            Objects = new List<object>();
        }

        public void AddHeader(string name)
        {
            Headers.Add(new TableHeader(name));
        }

        public void SetClassFor(int index, string name)
        {
            Headers[index].Class = name;
        }

        public void SetAbsoluteWidthFor(int index, int width)
        {
            Headers[index].AbsoluteWidth = width;
        }

        public void SetPercentageWidthFor(int index, int width)
        {
            Headers[index].PercentageWidth = width;
        }

        public void AddObject(object entity)
        {
            Objects.Add(entity);
        }

        public void SetCaption(string caption)
        {
            Caption = caption;
        }

        public void SetClass(string @class)
        {
            Class = @class;
        }

        public void SetId(string id)
        {
            Id = id;
        }

        public void SetIdFor(int index, string id)
        {
            Headers[index].Id = id;
        }
    }

    public class TableHeader
    {
        public TableHeader(string name)
        {
            Name = name;
        }

        public string Id { get; set; }
        public string Name { get; set; }
        public string Class { get; set; }
        public int? AbsoluteWidth { get; set; }
        public int? PercentageWidth { get; set; }
    }

    public interface ITableCreater
    {
        ITableOptions CreateTable { get; }
    }

    public interface ITableOptions
    {
        ITableOptions WithCaption(string caption);
        ITableHeaders WithHeaders();
        ITableOptions WithClass(string @class);
        ITableOptions WithId(string id);
    }

    public interface ITableHeaders
    {
        ITableHeaders Add(string name);
        ITableHeaders Class(string name);
        ITableHeaders Id(string id);
        ITableHeaders WithAbsoluteWidth(int width);
        ITableHeaders WithPercentageWidth(int width);
        ITableData WithData();
    }

    public interface ITableData
    {
        ITableData Add(object entity);
        string Render();
    }

    class TableDataImpl : ITableData
    {
        public TableModel Model { get; set; }

        public TableDataImpl(TableModel model)
        {
            Model = model;
        }

        public ITableData Add(object entity)
        {
            Model.AddObject(entity);
            return this;
        }

        public string Render()
        {

            string output = String.Empty;
            output += "<table";

            output += AddIdFor();
            output += AddClassFor();
            output += AddCaptionFor();

            output += ">";

            output += AddHeaders();

            foreach (var entity in Model.Rows)
            {
                output += "<tr>";
                output += entity.GetValuesAsSeperatedTdTags();
                output += "</tr>";
            }

            return output + "</table>";
        }

        private string AddHeaders()
        {
            string output = String.Empty;
            if (Model.Headers.Any())
            {
                output += "<tr>";
                foreach (var header in Model.Headers)
                {
                    output += "<th";
                    output += AddIdForHeader(header);
                    output += AddClassForHeader(header);
                    output += AddWidthForHeader(header);
                    output += ">";
                    output += header.Name;
                    output += "</th>";
                }
                output += "</tr>";
            }
            return output;
        }

        private string AddWidthForHeader(TableHeader header)
        {
            string output = String.Empty;
            if (header == null || !(header.PercentageWidth.HasValue || header.AbsoluteWidth.HasValue))
                return output;

            if (header.AbsoluteWidth.HasValue)
            {
                output += " width='" + header.AbsoluteWidth + "' ";
                return output;
            }

            if (header.PercentageWidth.HasValue)
            {
                output += " width='" + header.AbsoluteWidth + "%' ";
                return output;
            }
            return output;
        }

        private string AddClassForHeader(TableHeader header)
        {
            string output = String.Empty;
            if (header == null || String.IsNullOrWhiteSpace(header.Class))
                return output;

            if (!String.IsNullOrWhiteSpace(Model.Class))
                output += " class='" + header.Class + "' ";
            return output;
        }

        private string AddIdForHeader(TableHeader header)
        {
            string output = String.Empty;
            if (header == null || String.IsNullOrWhiteSpace(header.Id))
                return output;

            if (!String.IsNullOrWhiteSpace(Model.Caption))
                output += " id='" + header.Id  + "' ";
            return output;
        }

        private string AddCaptionFor()
        {
            string output = String.Empty;
            if (!String.IsNullOrWhiteSpace(Model.Caption))
                output += " Caption='" + Model.Caption + "' ";
            return output;
        }

        private string AddClassFor()
        {
            string output = String.Empty;
            if (!String.IsNullOrWhiteSpace(Model.Class))
                output += " class='" + Model.Class + "' ";
            return output;
        }

        private string AddIdFor()
        {
            string output = String.Empty;
            if (!String.IsNullOrWhiteSpace(Model.Id))
                output += " id='" + Model.Id + "' ";
            return output;
        }
    }

    public class TableHeadersImpl : ITableHeaders
    {

        private readonly TableModel _model;
        private int _index = -1;

        public TableHeadersImpl(TableModel model)
        {
            _model = model;
            _index = -1;
        }

        public int Index
        {
            get { return _index; }
            set { _index = value; }
        }

        public TableModel Model
        {
            get { return _model; }
        }

        public ITableHeaders Add(string name)
        {
            ++Index;
            Model.AddHeader(name);
            return this;
        }

        public ITableHeaders Class(string name)
        {
            Model.SetClassFor(Index, name);
            return this;
        }

        public ITableHeaders Id(string id)
        {
            Model.SetIdFor(Index, id);
            return this;
        }

        public ITableHeaders WithAbsoluteWidth(int width)
        {
            Model.SetAbsoluteWidthFor(Index, width);
            return this;
        }

        public ITableHeaders WithPercentageWidth(int width)
        {
            Model.SetPercentageWidthFor(Index, width);
            return this;
        }

        public ITableData WithData()
        {
            return new TableDataImpl(Model);
        }
    }

    public class TableOptionsImpl : ITableOptions
    {
        private readonly TableModel _model;

        public TableOptionsImpl(TableModel model)
        {
            _model = model;
        }

        public TableModel Model
        {
            get { return _model; }
        }

        public ITableOptions WithCaption(string caption)
        {
            Model.SetCaption(caption);
            return this;
        }

        public ITableHeaders WithHeaders()
        {
            return new TableHeadersImpl(Model);
        }

        public ITableOptions WithClass(string @class)
        {
            Model.SetCaption(@class);
            return this;
        }

        public ITableOptions WithId(string id)
        {
            Model.SetId(id);
            return this;
        }
    }

    public class Fluently : ITableCreater
    {
        public ITableOptions CreateTable
        {
            get { return new TableOptionsImpl(new TableModel()); }
        }
    }

    class Program
    {
        static void Main()
        {

            string output = new Fluently()
                .CreateTable
                .WithCaption("Cool table")
                .WithClass("Class")
                .WithId("#Id")
                .WithHeaders()
                    .Add("Name")
                        .Class("cool")
                        .WithAbsoluteWidth(100)
                    .Add("Age")
                        .Class("cool")
                        .WithAbsoluteWidth(100)
                .WithData()
                    .Add(new { Name = "Blair", Age = 100 })
                .Render();

            Console.WriteLine(output);
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Cheap Software Engineering Books For Sales

March 29, 2011 Leave a comment

Design Patterns in C# : $15 as new
Professional C# 2.0 : $10 – Markings made to item
Beginning ASP.NET MVC – $15
C# 3.0 in a nutshell – $15
.NET Domain Driven Design with C# – $15
C++ How to program Third Edition – $10 – Markings made to item
Visual C# 2005 – $10
Visual C++ 2005 = $15
ASP.NET 2.0 – $10
CLR via C# 2.0 – $10
Beginning Unix = $10
Prof ASP.NET 2.0 Ajax – $10
Beginning ASP.NET Databases – $10
Professional Hibernate – $10
Mac OS X Snow Leopard Portable Genius – $10
C# 2008 Thread Programming – $15
Event Driven Architecture – $15
Definitive guide to enterprise library – $10
Exploring C++ – $15
Introducing Microsoft LINQ – $10
Gurus guide to Transact SQL – $5
Linq unleashed – $15
Programming ms asp.net 3.5 – $10 – marked
working with ms dynamics crm 4.0 2nd edition – $15
programming visual basic 2005 the language – $15
professional sharepoint development 2007 – $15
microsoft .net framework 2.0 application development foundation training kit – $15
ms .net framework 3.5 wcf training kit – $15
ms applications = code + plus markup – $15
windows forms 2.0 programming – $10
databinding with windows forms 2.0 – $10
microsoft programming windows forms – $5 – marked
microsoft .net framework 3.5 – windows forms training kit – $15

Categories: Development

Simple Calculation Parser

March 26, 2011 2 comments

Doesnt support brackets yet. Ill add that later.

using System;
using System.Collections.Generic;
using System.IO;

namespace MathsCalcReader
{
    public class Program
    {
        static void Main()
        {
            Interpretor interpretor = new Interpretor("123 + 5 + 3 - 100");
            Console.WriteLine(interpretor.CalculateMathsExpression());
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }

    public class Interpretor
    {
        private readonly string _expression;
        private Queue<Token> _tokens;

        public Interpretor(string expression)
        {
            _expression = expression;
            _tokens = new Queue<Token>();
        }

        public int CalculateMathsExpression()
        {
            StringReader reader = new StringReader(_expression);

            while (reader.Peek() != -1)
            {
                char c = (char)reader.Read();
                if (Char.IsWhiteSpace(c)) continue;
                if (Char.IsDigit(c))
                {
                    AddDigits(reader, c);
                }
                else if (c == '+' || c == '-' || c == '/' || c == '*')
                {
                    AddOperator(c);
                }
            }

            return AccumulateTotal();
        }

        private int AccumulateTotal()
        {
            int total = 0;
            bool firstrun = true;

            while(_tokens.Count != 0)
            {
                if(firstrun)
                {
                    var op1 = _tokens.Dequeue();
                    var op = _tokens.Dequeue();
                    var op2 = _tokens.Dequeue();
                    total += op.Operator.Calc((int)op1.Value, (int)op2.Value);
                    firstrun = false;
                    continue;
                }
                var aop = _tokens.Dequeue();
                var aop2 = _tokens.Dequeue();
                total = aop.Operator.Calc(total, (int)aop2.Value);
            }
            return total;
        }

        private void AddDigits(StringReader reader, char c)
        {
            string temp = c.ToString();
            char p = (char)reader.Peek();
            if (Char.IsDigit(p))
            {
                p = (char)reader.Read();
                while (Char.IsDigit(p))
                {
                    temp += p;
                    p = (char)reader.Read();
                }
            }
            _tokens.Enqueue(new Token(Convert.ToInt32(temp)));
        }

        private void AddOperator(char c)
        {
            switch (c)
            {
                case '+':
                    _tokens.Enqueue(new Token(MathOperator.Addition));
                    break;
                case '-':
                    _tokens.Enqueue(new Token(MathOperator.Subtraction));
                    break;
                case '*':
                    _tokens.Enqueue(new Token(MathOperator.Multiplication));
                    break;
                case '/':
                    _tokens.Enqueue(new Token(MathOperator.Division));
                    break;
            }
        }
    }

    public class MathOperator
    {
        public Func<int, int, int> Calc;
        public char Value { get; private set; }
        public MathOperator(char value, Func<int,int,int> calc)
        {
            Calc = calc;
            Value = value;
        }

        public static MathOperator Addition = new MathOperator('+',(a,b) => a + b);
        public static MathOperator Subtraction = new MathOperator('-',(a,b) => a - b);
        public static MathOperator Multiplication = new MathOperator('*',(a,b) => a * b);
        public static MathOperator Division = new MathOperator('/', (a,b) => a / b);
    }

    public class Token
    {
        public int? Value { get; set; }
        public MathOperator Operator { get; set; }

        public Token(int value)
        {
            Value = value;
        }

        public Token(MathOperator op)
        {
            Operator = op;
        }
    }
}

Covariance in C#

February 28, 2011 1 comment

We are going to have a quick look at covariance in C#.

Only elements that can be covariant:

  • Interfaces
  • Delegates

Convariance is similar to Inheritance in the sense that if you have a class like IEnumerable which is covariant then you can assign a subclass of IEnumerable to IEnumerable.

Example: Base Person, Sub Class is Student. With Covariance you can assign IEnumerable to IEnumerable

You would just naturally think this would work but is has not until .NET 4 was introduced.

To allow convariance you must mark the generic parameter as out T as shown below in IIterable and IIterator. I wrote my own iterator design pattern based classes below to illustrate this.

you can only assign using references as shown in the main method. Assigning to base classes not interfaces won’t work.

using System;
using System.Collections.Generic;

namespace Variance
{


    public abstract class Entity<TKey> : IEquatable<Entity<TKey>>
    {

        public TKey Id { get; set; }

        protected Entity()
        {
            Id = default(TKey);
        }

        protected Entity(TKey identity)
        {
            Id = identity;
        }

        public override bool Equals(object obj)
        {
            var entity = obj as Entity<TKey>;
            return Equals(entity);
        }

        public bool Equals(Entity<TKey> other)
        {
            return other != null && Equals(Id, other.Id);
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
    }

    public class Person : Entity<int>
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return String.Format("{0} - {1}", Id, Name);
        }
    }

    public class Student : Person
    {
        public string Course { get; set; }
    }

    public interface IIterator<out T>
    {
        bool HasMoreElements { get; }
        T Current { get; }
        void Continue();
    }

    public interface IIterable<out T>
    {
        IIterator<T> GetIterator();
    }

    public class BasicList<T> : IIterable<T>
    {

        protected List<T> Items = new List<T>();

        public void AddItem(T item)
        {
            Items.Add(item);
        }

        public IIterator<T> GetIterator()
        {
            return new BlIterator<T>(Items);
        }

        public void PrinttoConsole()
        {
            foreach (var item in Items)
            {
                Console.WriteLine(item);
            }
        }

        public class BlIterator<T> : IIterator<T>
        {

            protected List<T> items = new List<T>(); 

            public BlIterator(List<T> items)
            {
                this.items = items;
            }

            private int index;

            public bool HasMoreElements
            {
                get { return index <= items.Count - 1; }
            }

            public T Current
            {
                get { return items[index]; }
            }

            public void Continue()
            {
                index++;
            }
        }


    }

    class Program
    {

        

        static void Main()
        {

            IIterable<Student> students = GetStudents();

            Print(students); // Covariance



            IIterable<Person> people = students; // Covariance

            Print(people);

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        public static IIterable<Student> GetStudents()
        {
            BasicList<Student> students = new BasicList<Student>();
            students.AddItem(new Student { Id = 1, Name = "Blair" });
            students.AddItem(new Student { Id = 2, Name = "Tim" });
            students.AddItem(new Student { Id = 3, Name = "Tom" });
            return students;
        }

        public static void Print(IIterable<Person> print) // Covariance
        {

            var iterator = print.GetIterator();

            while (iterator.HasMoreElements)
            {
                Console.WriteLine(iterator.Current);
                iterator.Continue();
            }
        }
    }
}

Blair…

Redirect to a safe location Error Action Filter in ASP.NET MVC

February 15, 2011 Leave a comment

I have an example of an error action filter on how you can move the user to a previously know safe location in mvc with the following action filter. I and an error to tempdata which you could look for in the site master to show the error.

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;

namespace Learning.ActionFilters
{
    public class RedirectToRouteErrorAttribute : FilterAttribute, IExceptionFilter
    {
        public IEnumerable<string> RouteValues { get; private set; }
        public string ErrorMessage { get; private set; }

        public RedirectToRouteErrorAttribute(string errormessage, params string[] tokens)
        {
            ErrorMessage = errormessage;
            RouteValues = tokens;
        }

        public void OnException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled)
                return;

            var items = from route in filterContext.RouteData.Values
                        join key in RouteValues on route.Key equals key
                        select route;

            var dict = new RouteValueDictionary(items);

            filterContext.Controller.TempData.Add("errormessage", ErrorMessage);
            filterContext.Result = new RedirectToRouteResult(dict);
            filterContext.HttpContext.Response.Clear();
            filterContext.ExceptionHandled = true;
        }
    }
}

// Here is an example of the usage
 [HttpPut]
 [ActionName("Edit")]
 [RedirectToRouteErrorAttribute("controller","action","id")]
 public virtual ActionResult EditUser(){}

You just specify which route values you want to keep so the RedirectToRouteResult work as required

Blair…

Cool Hamster

February 7, 2011 Leave a comment

<object type=”application/x-shockwave-flash” style=”outline:none;” data=”http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.swf?&#8221; width=”300″ height=”225″><param name=”movie” value=”http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.swf?”></param><param name=”AllowScriptAccess” value=”always”></param><param name=”wmode” value=”opaque”></param></object>Hamster

Categories: General
Follow

Get every new post delivered to your Inbox.