Translate

Friday 31 October 2014

1500 and Counting (no, not Tigers)

The most popular post in my blog is the one that has no tags to help search engines find it !! :)

Eh, what Google?

And I paid for Google AdWords spending an hour to figure out the right words to use ! :D

Wednesday 29 October 2014

A little more CSS magic !

One of the coolest things about CSS and jQuery is the simplicity that you can achieve in design.

Here is an example of a simple timeline that I created with css



The vertical line is not a .gif or an image but a line drawn, given co-ordinates in pixels.

The CSS for the same is in this fiddle that I have created for you to play around with.

And with a little jQuery, the animation of the timeline becomes simply simple!

Saturday 4 October 2014

The Repository Pattern - I (The Interface and ConcreteRepository)

The use case for a repository can be many - code, books, project etc but it is when these repos need to be combined and managed that the Repository pattern begins to make sense and the SharpRepository and the Unit of work technique to maintain/manage transactions for the different repositories, gain importance.

How the aggregate is defined and managed is how the question of whether 'one size fits all?' question will get an answer.

Although there is nothing new that could probably be added to the many excellent resources on the SharpRepository implementation, I did find some curious elements that were not as well or as clearly implemented in the many available resources on the web. This is the simplest of them all.

I will post my code first and continue with the explanations inline as and when and where I found it necessary.

The example that I have chosen is dependent on many interfaces and concrete implementations so posting the fully tested code will be done in stages.

The interface

using System.Collections.Generic;

namespace LinqExpressionsHashSet
{
    interface IRepository<T>
    {
            T GetById(int id);
            T GetByName(string name);
            IEnumerable<T> GetAll();
            IEnumerable<T> FindAll(IDictionary<string, object> propertyValuePairs);
            T FindOne(IDictionary<string, object> propertyValuePairs);
            T SaveOrUpdate(T entity);
            void Delete(T entity);  
    }
}

The concrete repository

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using SharpRepository.Repository.Queries;

namespace LinqExpressionsHashSet
{
        public class Repository<T> : IRepository<T>,IEnumerable<T> where T : class,IIdentifiable,new()
        {
          // for InMemoryRepository testing
            private readonly HashSet<T> data;
            private readonly IQueryable<T> queryableData;

        public Repository()
            : this(Enumerable.Empty<T>())
        {
        }
        public Repository(IEnumerable<T> testData)
        {
            data = new HashSet<T>(testData);
            queryableData = data.AsQueryable();
        }

        public Expression Expression { get; private set; }

        public Type ElementType { get; set; }

        public IQueryProvider Provider { get; private set; }

        public void Add(T entity)
        {
            data.Add(entity);
        }

        public void Add(IEnumerable<T> entities)
        {
            foreach (var e in entities)
            {
                data.Add(e);
            }
        }

        public void Update(T entity)
        {
            data.RemoveWhere(i => i.Id == entity.Id);
            data.Add(entity);
        }

        public void Update(IEnumerable<T> entities)
        {
            foreach (var e in entities)
            {
                Update(e);
            }
        }
        /* To use for Unit of Work
        public IBatch<T> BeginBatch()
        {
            return (IBatch<T>)data.ToList<T>();
        }
        */
        public void Delete(T entity)
        {
            data.RemoveWhere(i => i.Id == entity.Id);
        }

        public void Delete(IEnumerable<T> entities)
        {
            foreach (var e in entities)
            {
                data.RemoveWhere(x => x.Id == e.Id); // The id is from MongoDB
            }
        }

        public T Find(Expression<Func<T, bool>> predicate, IQueryOptions<T> queryOptions = null)
        {
//            Extracting the lambda expression
            Expression<Func<T, bool>> ep = Expression.Lambda<Func<T, bool>>(predicate);
            // without queryOptions
            return queryableData.First(ep);
        }

/*
            //Need to test this
        public TResult Find<TResult>(Expression<Func<T, bool>> predicate, Expression<Func<T, TResult>> selector,
                                     IQueryOptions<T> queryOptions = null)
        {
            Expression<Func<T, TResult>> ep = Expression.Lambda<Func<T, TResult>>(selector);
            IEnumerable<TResult> someResults = queryableData.Select(selector);
            Expression<Func<T, bool>> exp = Expression.Lambda<Func<T, bool>>(predicate);
            TResult tt = default(TResult); // to escape uninitialized compiler error and null.
            foreach (TResult a in someResults)
            {
                var e = queryableData.First(exp);
                if (data.Contains(e))
                {
                    tt = a;
                    break;
                }
            }
            return tt;
        }
*/
        public bool Exists(Expression<Func<T, bool>> predicate)
        {
            Expression<Func<T, bool>> ep = Expression.Lambda<Func<T, bool>>(predicate);
            Func<T, bool> fexp = ep.Compile();
            var t = fexp(new T()); // Returns bool from the expression

            return t; // This is not the correct return value. Used only to pass the compiler.
        }

            /* To be used with EF
            protected DbSet<T> DbSet;

            public Repository(DbContext dataContext)
            {
                DbSet = dataContext.Set<T>();
            }
         
            public void Insert(T entity)
            {
                DbSet.Add(entity);
            }

            public void Delete(T entity)
            {
                DbSet.Remove(entity);
            }

            public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
            {
                return DbSet.Where(predicate);
            }

            public IQueryable<T> GetAll()
            {
                return DbSet;
            }

            public T GetById(int id)
            {
                return DbSet.Find(id);
            }
             */
        }
    }

and an identifiable interface for in memory and MongoDB implementation. This could be substituted with an IEntity interface that can help provide the 'id' but on this (the BS, that is :)) I will post later. This is being used to query an expression with an 'id' in the Delete method above.

// The Identity interface

using MongoDB.Bson;
namespace LinqExpressionsHashSet
{
    public interface IIdentifiable : IIdentifiable<ObjectId>
    {
        string StringId { get; }
    }
    public interface IIdentifiable<T>
    {
        T Id { get; }
    }

}

// The Project repo
using System;

namespace LinqExpressionsHashSet
{
    public class Project:IIdentifiable
    {
        public int projectId { get; set; }
        public string name{get;set;}
        public DateTime createdOn { get; set; }
        public string createdBy { get; set; }
    }
}

More to follow...:)

Wednesday 1 October 2014

The de-generations

It must be a serious set of nutcases that are going around asking "Do you write your own blog?". The level of intelligence has de-generated to such an extent that it is not even worth mentioning to look at the paradox in the question - how can it be my blog if I do not write it ? :D

Go, bite elsewhere or go get your brains or head examined and if there is no cure, just take the damn thing off your shoulders (or have it taken off you there are many obliging psycho morons around nowadays), it is not worth carrying that much weight...:D