Monday, April 29, 2013

Uncomfortable during the interview?

Imagining your interviewer naked may be a bad idea sometimes. No, wrong - it is always bad idea. Try this instead:


You know what to do with it, you just can not do worse.

P.S. Also these would be a great questions to fire in return: Interview Questions for Potential Employers

Sunday, April 28, 2013

ASP.NET + No-SQL. Part I - RavenDb

RavenDb is great native LINQ no-SQL database which is under active development. It has enormous community support and loads of resources which can help you get started (I wish they had this open course at my time).
Below is the code I ended up with after some time of polishing and tweaking and which finally worked for me. For a quick-start convenience I am providing the instructions in sequential steps.

1. Download and install RavenDB Client nuget package from Hibernating Rhinos.

2. Add "RavenDb" connection string to your web.config file. It is not necessary to use this name but if you'd ever consider AppHarbor hosting with one of the RaveDb add-ons, the deployment script will automatically place correct connection string if it will find "RavenDb" key. And we love automation.

3. The core access class for the Raven API is Document Store. It is expensive to create but it is thread-safe so we can use one singleton instance of it throughout our application life cycle. To achieve that we place the following code in out Global.asax.cs file:

private const string RavenSessionKey = "OpenHouseRaven.Session";
private static DocumentStore documentStore;

public WebApiApplication()
{
    BeginRequest += (sender, args) =>
        HttpContext.Current.Items[RavenSessionKey] = documentStore.OpenSession();
    EndRequest += (sender, args) =>
    {
        var disposable = HttpContext.Current.Items[RavenSessionKey] as IDisposable;
        if (disposable != null) disposable.Dispose();
    };
}
protected void InitializaeRavenDbStore()
{
    documentStore = new DocumentStore { Url = ConfigurationManager.ConnectionStrings["ravenDb"].ConnectionString };
    documentStore.Initialize();
}
public static IDocumentSession CurrentRavenSession
{
    get { return (IDocumentSession)HttpContext.Current.Items[RavenSessionKey]; }
}


Add call to InitializaeRavenDbStore() to the end of Application_Start method which should be already there. In this code we initialized DocumentStore class, provided infrastructure to store Raven Document Session and altered WebApiApplication constructor, attaching handlers to BeginRequest and EndRequest events to properly create and dispose the Session object for each request.

4. Next is repository class which will encapsulate all database interaction. Raven is natural with LINQ and generics, so repository can be created to handle specific type.

public class RavenRepository<T>
{
    protected IDocumentSession ravenSession;

    public RavenRepository(IDocumentSession session)
    {
        ravenSession = session;
    }
    public virtual T Find(string id)
    {
        if (string.IsNullOrEmpty(id)) return default(T);
        var item = ravenSession.Load<T>(id);
        return item;
    }
    public virtual IEnumerable<T> FindAll(Func<T, bool> predicate)
    {
        return predicate == null
                    ? ravenSession.Query<T>()
                    : ravenSession.Query<T>().Where(predicate);
    }
    public virtual List<T> InsertOrUpdate(List<T> list)
    {
        foreach (var entity in list)
        {
            ravenSession.Store(entity);
        }
        ravenSession.SaveChanges();
        return list;
    }
    public virtual void Delete(string id)
    {
        if (string.IsNullOrEmpty(id)) return;
        T entity = Find(id);
        ravenSession.Delete(entity);
        ravenSession.SaveChanges();
    }
}

The Raven Document Session object is being injected into the class for better testability. And we love testability.

5. And now the code which all above was preparing us for - the usage:

var repo = new RavenRepository<Person>(WebApiApplication.CurrentRavenSession, null);
var existing = repo.FindAll(p => p.Name == "Smith").FirstOrDefault();


Pretty simple construction with few small tricks - I hope it will save you some start time.

Thursday, April 04, 2013

The story of my life


© 2008-2013 Michael Goldobin. All rights reserved