Andrew Rea - A Developer On A Few Platforms

C#, JAVA, ASP.NET, C++, ACTION SCRIPT

Andrew Rea - For March 2010

  1. First toe in the water with Object Databases : DB4O

    I have been wanting to have a play with Object Databases for a while now, and today I have done just that.  One of the obvious choices I had to make was which one to use.  My criteria for choosing one today was simple, I wanted one which I could literally wack in and start using, which means I wanted one which either had a .NET API or was designed/ported to .NET.  My decision was between two being:

    I went for db4o for the single reason that it looked like I could get it running and integrated the quickest.  I am making a Blogging application and front end as a project with which I can test and learn with these object databases.  Another requirement which I thought I would mention is that I also want to be able to use the said database in a shared hosting environment where I cannot install, run and maintain a server instance of said object database.  I can do exactly this with db4o. I have not tried to do this with MongoDb at time of writing.  There are quite a few in the industry now and you read an interesting post about different ones and how they are used with some of the heavy weights in the industry here : http://blog.marcua.net/post/442594842/notes-from-nosql-live-boston-2010

    In the example which I am building I am using StructureMap as my IOC.  To inject the object for db4o I went with a Singleton instance scope as I am using a single file and I need this to be available to any thread on in the process as opposed to using the server implementation where I could open and close client connections with the server handling each one respectively.  Again I want to point out that I have chosen to stick with the non server implementation of db4o as I wanted to use this in a shared hosting environment where I cannot have such servers installed and run.

    
        public static class Bootstrapper
        {
            public static void ConfigureStructureMap()
            {
                ObjectFactory.Initialize(x => x.AddRegistry(new MyApplicationRegistry()));
            }
        }
    
        public class MyApplicationRegistry : Registry
        {
            public const string DB4O_FILENAME = "blog123";
    
            public string DbPath
            {
                get
                {
                    return Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(IBlogRepository)).Location), DB4O_FILENAME);
                }
            }
    
            public MyApplicationRegistry()
            {
                For<IObjectContainer>().Singleton().Use(
                    () => Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), DbPath));
    
                Scan(assemblyScanner =>
                {
                    assemblyScanner.TheCallingAssembly();
                    assemblyScanner.WithDefaultConventions();
                });
            }
        }
    

    image

    So my code above is the structure map plumbing which I use for the application.  I am doing this simply as a quick scratch pad to play around with different things so I am simply segregating logical layers with folder structure as opposed to different assemblies.  It will be easy if I want to do this with any segment but for the purposes of example I have literally just wacked everything in the one assembly.  You can see an example file structure I have on the right.  I am planning on testing out a few implementations of the object databases out there so I can program to an interface of IBlogRepository

    One of the things which I was unsure about was how it performed under a multi threaded environment which it will undoubtedly be used 9 times out of 10, and for the reason that I am using the db context as a singleton, I assumed that the library was of course thread safe but I did not know as I have not read any where in the documentation, again this is probably me not reading things correctly.  In short though I threw together a simple test where I simply iterate to a limit each time kicking a common task off with a thread from a thread pool.  This task simply created and added an random Post and added it to the storage.

    The execution of the threads I put inside the Setup of the Test and then simply ensure the number of posts committed to the database is equal to the number of iterations I made; here is the code I used to do the multi thread jobs:

    
            [TestInitialize]
            public void Setup()
            {
                var sw = new System.Diagnostics.Stopwatch();
                sw.Start();
                var resetEvent = new ManualResetEvent(false);
                ThreadPool.SetMaxThreads(20, 20);
                for (var i = 0; i < MAX_ITERATIONS; i++)
                {
                    ThreadPool.QueueUserWorkItem(delegate(object state)
                                                     {
                                                         var eventToReset = (ManualResetEvent)state;
                                                         var post = new Post
                                                                        {
                                                                            Author = MockUser,
                                                                            Content = "Mock Content",
                                                                            Title = "Title"
                                                                        };
                                                         Repository.Put(post);
    
                                                         var counter = Interlocked.Decrement(ref _threadCounter);
                                                         if (counter == 0)
                                                             eventToReset.Set();
    
                                                     }, resetEvent);
                }
    
                WaitHandle.WaitAll(new[] { resetEvent });
                sw.Stop();
                Console.WriteLine("{0:00}.{1:00} seconds", sw.Elapsed.Seconds, sw.Elapsed.Milliseconds);
            }
    

     

    image

     

    I was not doing this to test out the speed performance of db4o but while I was doing this I could not help but put in a StopWatch and see out of sheer interest how fast it would take to insert a number of Posts.  I tested it out in this case with 10000 inserts of a small, simple POCO and it resulted in an average of:

     899.36 object inserts / second. 

    Again this is just  simple crude test which came out of my curiosity at how it performed under many threads when using the non server implementation of db4o. The spec summary of the computer I used is as follows:

    image

    With regards to the actual Repository implementation itself, it really is quite straight forward and I have to say I am very surprised at how easy it was to integrate and get up and running.  One thing I have noticed in the exposure I have had so far is that the Query returns IList<T> as opposed to IQueryable<T> but again I have not looked into this in depth and this could be there already and if not they have provided everything one needs to make there own repository.  An example of a couple of methods from by db4o implementation of the BlogRepository is below:

    
        public class BlogRepository : IBlogRepository
        {
            private readonly IObjectContainer _db;
    
            public BlogRepository(IObjectContainer db)
            {
                _db = db;
            }
    
            public void Put(DomainObject obj)
            {
                _db.Store(obj);
            }
    
            public void Delete(DomainObject obj)
            {
               _db.Delete(obj);
            }
    
            public Post GetByKey(object key)
            {
                return _db.Query<Post>(post => post.Key == key).FirstOrDefault();
            }
    

    Anyways I hope to get a few more implementations going of the object databases and literally just get familiarized with them and the concept of no sql databases.

    Cheers for now,

    Andrew

    UPDATE 2010-03-18

    I feel a bit stupid here as the above is great and all, but if I do not call commit on the database then the values will remain in RAM, hence the speed I reported above.  In actual fact I reduced the number of inserts I am testing against to 1000 and each insert on each thread I make I also commit the object.  So each thread does the following:

    1. Creates a Post
    2. Saves the Post
    3. Commits the changes to the file.

    With the addition of adding the commit to the job the actual performance works out on the same machine spec as above as:

    33.2 object insert and commit / second

    I have added a Commit method onto the IBlogRepository and implement this in the concrete.

    
            public void Commit()
            {
                _db.Commit();
            }
    

     

    image

    I will also point out that omitting the commit is also great for tests where you have then an in memory implementation of your data store, where in the past when developing against an RDBMS I would use Sqlite for such a thing.

    Posted by Andrew Rea on March 15 at 5:15 PM

  2. ASP.NET MVC 2 : The view 'Index' or its master was not found

    I was literally setting a new project yesterday to have a play with the released version of ASP.NET MVC 2 and came across a subtle couple of things which when you know, like everything, is easy.

    I am creating a small test application which is another blog one, but this time I also want to use an Object DB or many, the first being MONGO, but anyway.  I added a new Area to my project being the Blog area, added the controller and a view and hit F5.

    The view 'Index' or its master was not found. The following locations were searched:

    Because my area was called Blog, naturally I want the controller to be called BlogController.  The cause and the solution are inside the AreaRegistration file.  When you create your new area you should notice your default route inside this registration file and notice there is no default controller specified, which is correct because at time of creation you will not have a controller inside the area.

    
            public override void RegisterArea(AreaRegistrationContext context)
            {
                context.MapRoute(
                    "Blog_default",
                    "Blog/{controller}/{action}/{id}",
                    new { action = "Index", id = "" }
                );
            }
    

     

    So add in the default controller and everything is back to normal.  Also, if you do not add this controller and for example add a break point to the return View() of the Index Action on your controller, you will see that it does get hit, it is just the locating of the View which fails.  I am sure there is more plumbing that can be done to enable the location of these views without explicitly stating the default controller but at time of writing I do not know. 

    
            public override void RegisterArea(AreaRegistrationContext context)
            {
                context.MapRoute(
                    "Blog_default",
                    "Blog/{controller}/{action}/{id}",
                    new {controller="Blog", action = "Index", id = "" }
                );
            }
    

    Cheers for now,

    Andrew

    Posted by Andrew Rea on March 14 at 6:48 AM

  3. Compiling examples for consuming the REST Endpoints for WCF Service using Agatha

    I recently made two contributions to the Agatha Project by Davy Brion over on Google Code, and one of the things I wanted to follow up with was a post showing examples and some, seemingly required tid bits.  The contributions which I made where:

    • To support StructureMap
    • To include REST (JSON and XML) support for the service contract

    The examples which I have made, I want to format them so they fit in with the current format of examples over on Agatha and hopefully create and submit a third patch which will include these examples to help others who wish to use these additions.

    Whilst building these examples for both XML and JSON I have learnt a couple of things which I feel are not really well documented, but are extremely good practice and once known make perfect sense.  I have chosen a real basic e-commerce context for my example Requests and Responses, and have also made use of the excellent tool AutoMapper, again on Google Code.

    Setting the scene

    I have followed the Pipes and Filters Pattern with the IQueryable interface on my Repository and exposed the following methods to query Products:

    
    IQueryable<Product> GetProducts();
    
    
    IQueryable<Product> ByCategoryName(this IQueryable<Product> products, string categoryName)
    
    
    Product ByProductCode(this IQueryable<Product> products, String productCode)
    

    I have an interface for the IProductRepository but for the concrete implementation I have simply created a protected getter which populates a private List<Product> with 100 test products with random data.  Another good reason for following an interface based approach is that it will demonstrate usage of my first contribution which is the StructureMap support.  Finally the two Domain Objects I have made are Product and Category as shown below:

    
        public class Product
        {
            public String ProductCode { get; set; }
            public String Name { get; set; }
            public Decimal Price { get; set; }
            public Decimal Rrp { get; set; }
            public Category Category { get; set; }
        }
    

     

    
        public class Category
        {
            public String Name { get; set; }
        }
    

     

    Requirements for the REST Support

    One of the things which you will notice with Agatha is that you do not have to decorate your Request and Response objects with the WCF Service Model Attributes like DataContract, DataMember etc… Unfortunately from what I have seen, these are required if you want the same types to work with your REST endpoint.  I have not tried but I assume the same result can be achieved by simply decorating the same classes with the Serializable Attribute.  Without this the operation will fail.

    Another surprising thing I have found is that it did not work until I used the following Attribute parameters:

    • Name
    • Namespace

    e.g.

    
        [DataContract(Name = "GetProductsRequest", Namespace = "AgathaRestExample.Service.Requests")]
        public class GetProductsRequest : Request
        {
        }
    

     

    Although I was surprised by this, things kind of explained themselves when I got round to figuring out the exact construct required for both the XML and the REST.  One of the things which you already know and are then reminded of is that each of your Requests and Responses ultimately inherit from an abstract base class respectively. This information needs to be represented in a way native to the format being used.  I have seen this in XML but I have not seen the format which is required for the JSON.

    JSON Consumer Example

    I have used JQuery to create the example and I simply want to make two requests to the server which as you will know with Agatha are transmitted inside an array to reduce the service calls.  I have also used a tool called json2 which is again over at Google Code simply to convert my JSON expression into its string format for transmission.  You will notice that I specify the type of Request I am using and the relevant Namespace it belongs to.  Also notice that the second request has a parameter so each of these two object are representing an abstract Request and the parameters of the object describe it.

    
        <script type="text/javascript">
            var bodyContent = $.ajax({
            url: "http://localhost:50348/service.svc/json/processjsonrequests",
                global: false,
                contentType: "application/json; charset=utf-8",
                type: "POST",
                processData: true,
                data: JSON.stringify([
                { __type: "GetProductsRequest:AgathaRestExample.Service.Requests" },
                { __type: "GetProductsByCategoryRequest:AgathaRestExample.Service.Requests", CategoryName: "Category1" }
                ]),
                dataType: "json",
                success: function(msg) {
                    alert(msg);
                }
            }).responseText;
    
        </script>
    

     

    XML Consumer Example

    For the XML Consumer example I have chosen to use a simple Console Application and make a WebRequest to the service using the XML as a request.  I have made a crude static method which simply reads from an XML File, replaces some value with a parameter and returns the formatted XML.  I say crude but it simply shows how XML Templates for each type of Request could be made and then have a wrapper utility in whatever language you use to combine the requests which are required.  The following XML is the same Request array as shown above but simply in the XML Format.

    
    <?xml version="1.0" encoding="utf-8" ?>
    <ArrayOfRequest xmlns="http://schemas.datacontract.org/2004/07/Agatha.Common" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Request i:type="a:GetProductsRequest" xmlns:a="AgathaRestExample.Service.Requests"/>
      <Request i:type="a:GetProductsByCategoryRequest" xmlns:a="AgathaRestExample.Service.Requests">
        <a:CategoryName>{CategoryName}</a:CategoryName>
      </Request>
    </ArrayOfRequest>
    

     

    It is funny because I remember submitting a question to StackOverflow asking whether there was a REST Client Generation tool similar to what Microsoft used for their RestStarterKit but which could be applied to existing services which have REST endpoints attached.  I could not find any but this is now definitely something which I am going to build, as I think it is extremely useful to have but also it should not be too difficult based on the information I now know about the above.  Finally I thought that the Strategy Pattern would lend itself really well to this type of thing so it can accommodate for different languages.

    I think that is about it, I have included the code for the example Console app which I made below incase anyone wants to have a mooch at the code.  As I said above I want to reformat these to fit in with the current examples over on the Agatha project, but also now thinking about it, make a Documentation Web method…{brain ticking} :-)

    Cheers for now and here is the final bit of code:

    
            static void Main(string[] args)
            {
                var request = WebRequest.Create("http://localhost:50348/service.svc/xml/processxmlrequests");
                request.Method = "POST";
                request.ContentType = "text/xml";
                using(var writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.WriteLine(GetExampleRequestsString("Category1"));
                }
                var response = request.GetResponse();
                using(var reader = new StreamReader(response.GetResponseStream()))
                {
                    Console.WriteLine(reader.ReadToEnd());
                }
                Console.ReadLine();
            }
    
            static string GetExampleRequestsString(string categoryName)
            {
                var data = File.ReadAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ExampleRequests.xml"));
                data = data.Replace("{CategoryName}", categoryName);
                return data;
            }
        }
    
    Posted by Andrew Rea on March 09 at 4:43 PM

© Copyright 2010 Powered by AtomSite 1.4.0.0