Kash Farooq's software development blog

.NET Developer

Posts Tagged ‘C#’

AutoMapper: Mapping nested complex types

Posted by Kash Farooq on August 20, 2012

Some production code I was working on  wasn’t working as expected, so I thought I’d spike it out.

AutoMapper allows you to map between, say, a service layer and a DTO without you having to write hardly any code. Install it with NuGet.

Here is an example. I have some types in my service layer:


namespace Automapper.Spike.Example1.Contract
{
  public class CreateOrderRequest
  {
    public int Id { get; set; }
    public int NumberOfItems { get; set; }
    public Customer Customer { get; set; }
  }

  public class Customer
  {
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Postcode { get; set; }
   }
}

I want to map these to a DTO layer for storage:


namespace Automapper.Spike.Example1.Dto
{
  public class Order
  {
    public int Id { get; set; }
    public int NumberOfItems { get; set; }
    public Customer Customer { get; set; }
  }

  public class Customer
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Postcode { get; set; }
  }
}

I just need to tell AutoMapper that I want it to map between these types:


public class MapperConfiguration
{
  public void Configure()
  {
    Mapper.CreateMap<Customer, Dto.Customer>()
      .ForMember(x=>x.Name,o=>o.MapFrom(src=>src.FullName));
    Mapper.CreateMap<CreateOrderRequest, Dto.Order>();
  }
}

That’s all the code you need. If FullName was just called Name, I wouldn’t even need the extra ForMember line.

Here is a test to check it all works:


[TestFixture]
public class Example1Test
{
  [Test]
  public void CheckMappings()
  {
    new MapperConfiguration().Configure();
    try
    {
      Mapper.AssertConfigurationIsValid();
    }
    catch (Exception e)
    {
      Console.WriteLine(e);
      Console.WriteLine(e.InnerException);
      throw;
    }

    var createOrderRequest = CreateTestOrderRequest();
    var order = Mapper.Map<Order>(createOrderRequest);

    order.Customer.Should().NotBeNull();
    order.Customer.Id.Should().Be(3);
    order.Customer.Name.Should().Be("Bob Smith");
    order.Customer.Postcode.Should().Be("W1 1AA");
    order.Id.Should().Be(1);
    order.NumberOfItems.Should().Be(2);
  }

  private static CreateOrderRequest CreateTestOrderRequest()
  {
    return new CreateOrderRequest
    {
      Id = 1,
      NumberOfItems = 2,
      Customer = new Customer
      {
        Id = 3,
        FullName = "Bob Smith",
        Postcode = "W1 1AA"
      }
    };
  }
}

Note the Mapper.AssertConfigurationIsValid() method. When you call this, AutoMapper will check you have provided enough configuration info.

Advertisements

Posted in .NET | Tagged: , , | Leave a Comment »

Creating dynamic objects from JSON in .NET 4

Posted by Kash Farooq on July 23, 2012

I’m seeing quite a lot of people arriving at this blog with searches such as “datacontractjsonserializer .net 4”.

They end up at one of my old posts: Creating .NET objects from JSON using DataContractJsonSerializer. Implementing this will work in .NET 4, but why would you want to use DataContractJsonSerializer when you can use .NET 4 dynamic objects instead?

So, here is a very short blog post describing how to do just that.

I’m using some JSON I got from the Rotten Tomatoes API (which is excellent by the way). The JSON is all in one line so click hover over it and click the View Source icon to see it in a scrollable pop-up window.

{"id":11292,"title":"Star Wars: Episode IV - A New Hope","year":1977,"genres":["Action & Adventure","Mystery & Suspense","Science Fiction & Fantasy"],"mpaa_rating":"PG","runtime":105,"critics_consensus":"A legendarily expansive and ambitious start to the sci-fi saga, George Lucas opened our eyes to the possiblites of blockbuster filmmaking and things have never been the same.","release_dates":{"theater":"1977-05-25","dvd":"2004-09-21"},"ratings":{"critics_rating":"Certified Fresh","critics_score":94,"audience_rating":"Upright","audience_score":93},"synopsis":"","posters":{"thumbnail":"http://content9.flixster.com/movie/10/94/47/10944715_mob.jpg","profile":"http://content9.flixster.com/movie/10/94/47/10944715_pro.jpg","detailed":"http://content9.flixster.com/movie/10/94/47/10944715_det.jpg","original":"http://content9.flixster.com/movie/10/94/47/10944715_ori.jpg"},"abridged_cast":[{"name":"Mark Hamill","id":"162665747","characters":["Luke Skywalker"]},{"name":"Harrison Ford","id":"162661579","characters":["Han Solo"]},{"name":"Carrie Fisher","id":"162663355","characters":["Princess Leia Organa"]},{"name":"Peter Cushing","id":"162658723","characters":["Grand Moff Tarkin"]},{"name":"Alec Guinness","id":"162655900","characters":["Ben Obi-Wan Kenobi"]}],"abridged_directors":[{"name":"George Lucas"}],"studio":"20th Century Fox","alternate_ids":{"imdb":"0076759"},"links":{"self":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292.json","alternate":"http://www.rottentomatoes.com/m/star_wars/","cast":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/cast.json","clips":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/clips.json","reviews":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/reviews.json","similar":"http://api.rottentomatoes.com/api/public/v1.0/movies/11292/similar.json"}}

I have put the above JSON into a text file which I’ll access via a test:

[Test]
public void DeserializeJsonWithDynamic()
{
  string starWarsAsJson = File.ReadAllText(@"DataGateways\RottenTomatoes\StarWars.json");
  dynamic starWarsAsDynamic = Json.Decode(starWarsAsJson);
  Console.WriteLine("Title: "+starWarsAsDynamic.Title);
  Console.WriteLine("Year: " + starWarsAsDynamic.Year);
  Console.WriteLine("Original Poster: " + starWarsAsDynamic.Posters.Original);
}

In the above code I’m using Json.Decode, which is in System.Web.Helpers, to create a dynamic object out of the JSON text.

Running the test results in the following output:

Title: Star Wars: Episode IV - A New Hope
Year: 1977
Original Poster: http://content9.flixster.com/movie/10/94/47/10944715_ori.jpg

Very cool. Notice I went down the JSON object hierarchy to get Posters.Original.

Posted in .NET | Tagged: , , , | 2 Comments »

Creating a database schema with Fluent NHibernate

Posted by Kash Farooq on July 17, 2012

If you create your model in C# first, and then want to create a database schema that matches that model, you can do this easily with Fluent NHibernate.

First, you need some sort of Data Access Initialization class.

public class DataAccessInitializer
{
  private static ISessionFactory sessionFactory;
  private readonly FluentConfiguration fluentConfiguration;
  private Configuration nhibernateConfiguration;

  public DataAccessInitializer()
  {
    //Fluently configure nHibernate and save the nHibernate config that has been created by Fluent
    fluentConfiguration = CreateFluentConfiguration().ExposeConfiguration(cfg => nhibernateConfiguration = cfg);
  }

  public Configuration NhibernateConfiguration
  {
    get { return nhibernateConfiguration; }
  }

  public ISessionFactory CreateSessionFactory()
  {
    return sessionFactory ?? (sessionFactory = fluentConfiguration.BuildSessionFactory());
  }

  private static FluentConfiguration CreateFluentConfiguration()
  {
    var entitiesToMapConfiguration = new EntitiesToMapConfiguration();
    return Fluently.Configure()
        .Database(MsSqlConfiguration.MsSql2008
                        .ConnectionString(x => x.Server(".")
                        .Database("nHibernateAndWebSessionManagement")
                        .TrustedConnection()))
        .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Movie>(entitiesToMapConfiguration))); //Movie is one of my entities that needs mapping
  }

  //Class to limit the objects Fluent is interested in
  private class EntitiesToMapConfiguration : DefaultAutomappingConfiguration
  {
    public override bool ShouldMap(Type type)
    {
      return type.Namespace == "MovieSearch.DataAccess.Entities"; //only use classes in this namespace.
    }
  }
}

You could use this to create your Session Factory for any app. Note that I’ve created a EntitiesToMapConfiguration class to limit the types that Fluent is interested in. I don’t want NHibernate to start looking for a DataAccessInitializer table.

I’ve done one extra thing that you don’t need if you just want to create sessions from the Session Factory: I’ve called FluentConfiguration.ExposeConfiguration to save the NhibernateConfiguration into a private variable. I have also created a public NhibernateConfiguration property that exposes this so that it can specifically be used by the following code to create the database schema:


[TestFixture]
public class DataAccessTest
{
  private static void BuildSchema(Configuration cfg)
  {
    new SchemaUpdate(cfg).Execute(true, true);
  }

  [Test]
  [Explicit]
  public void CreateSchema()
  {
    var dataAccessService = new DataAccessInitializer();
    dataAccessService.CreateSessionFactory();
    BuildSchema(dataAccessService.NhibernateConfiguration);
  }
}

I’ve wrapped the runner in an NUnit test, and used the ExplicitAttribute to prevent the test from running accidentally – it won’t run if you chose to run all tests in a solution, only if you run that one test explicitly.

Posted in .NET, Fluent NHibernate, NHibernate | Tagged: , , , | Leave a Comment »

More TDD with wrapper classes

Posted by Kash Farooq on June 23, 2012

I have previously blogged about using wrapper classes to test the hard to test. In that post I made things easy for myself by using the parameterless constructor of the SmtpClient class.

I thought I’d revisit this area of testing, and try something different. This time I’ve used Moq rather than Rhino Mocks for starters. But I’m also going to pretend that SmtpClient does not have a parameterless constructor.  If a class you need to make testable does not have a parameterless constructor, it makes things a bit trickier:

public class SystemUnderTest
{
  public void MethodToBeTested()
  {
    var mailMessage = new MailMessage { Subject = "Hello", From = new MailAddress("Me@Me.com") };
    mailMessage.To.Add(new MailAddress("You@You.com"));
    var smtpClient = new SmtpClient("smtp.kashfarooq.com", 25);
    smtpClient.Send(mailMessage);
  }
}

A number of things in the above code need to be addressed and tested. The SMTP client is being instantiated in the method with the host and port being sent in via a the constructor, which makes things awkward to test. Apart from that complication, I’d like to make sure the correct host and port are being used. And I’d also like to make sure the correct details are being set in the MailMessage object.

First, we need an interface so we can mock the Send method. This matches the SmtpClient.Send method exactly:

public interface ISmtpClient
{
  void Send(MailMessage mailMessage);
}

We also need a wrapper class that will wrap SmtpClient and the constructor we are planning to use:

public class SmtpClientWrapper : SmtpClient, ISmtpClient
{
  public SmtpClientWrapper(string host, int port) : base(host, port)  { }
}

The above wrapper class inherits the interface defined above and the class we are trying to make testable: SmtpClient. And as it derives from SmtpClient, it automatically implements ISmtpClient.Send(MailMessage).

Next, we’ll create a suitable constructor for our SystemUnderTest class so that we can inject in some mocks. Because the MethodToBeTested creates the SmtpClient object, I’m going to use the “Using a Func instead of a Factory” trick:

private readonly Func<string, int, ISmtpClient> createSmtpClient;

public SystemUnderTest(Func<string, int, ISmtpClient> createSmtpClient)
{
  this.createSmtpClient = createSmtpClient;
}

public SystemUnderTest() : this((host,port) => new SmtpClientWrapper(host, port)) {}

So, what’s going on here? I have created a Func that will take a string and int (the host and port) and return an ISmtpClient. From my test I’ll use the first constructor. The production code will use the second constructor. In both cases, the Func supplied is stored in createSmtpClient – and this will be called from MethodToBeTested to actually create the SmtpClient.

I’m now in full control of all the dependencies. I can catch the MailMessage parameter sent to the Send method, and the host and port name sent to the createSmtpClient Func, which ultimately gets sent to to the SmtpClient(string host, int port) constructor.

And here is the test that creates a mock ISmtpClient and a Func that returns it, and also catches the parameters sent to it so the appropriate asserts can be done:

[Test]
public void CorrectEmailSentViaTheCorrectSmtpHost()
{
  string actualHostName=string.Empty;
  int actualPort=0;
  MailMessage actualMailMessage = null;

  var mockSmtpClient = new Mock<ISmtpClient>();
  mockSmtpClient
     .Setup(x => x.Send(It.IsAny<MailMessage>()))
     .Callback((MailMessage message) => actualMailMessage = message); //Catch the MailMessage sent to the Send method

  //Func to return an ISmtpClient and catch data sent to it
  Func<string, int, ISmtpClient> createSmtpClient = (host, port) =>
      {
         actualHostName = host; //catch the hostname used
         actualPort = port; //catch the port used
         return mockSmtpClient.Object; //return mocked SmtpClient
  };

  //Call system under test
  var sut = new SystemUnderTest(createSmtpClient);
  sut.MethodToBeTested();

  //Asserts
  actualHostName.Should().Be("smtp.kashfarooq.com");
  actualPort.Should().Be(25);
  actualMailMessage.Subject.Should().Be("Hello");
  actualMailMessage.From.Address.Should().Be("Me@Me.com");
  actualMailMessage.To[0].Address.Should().Be("You@You.com");
}

[Incidentally, I’m using the excellent FluentAssertions in my asserts.]

Posted in .NET, Moq, Test Driven Development | Tagged: , , , | Leave a Comment »

How to test DateTime.Now

Posted by Kash Farooq on June 17, 2012

A colleague new to TDD asked me how to do this recently, so I thought I’d blog it.

Here is some code we want to bring under test:

public void SomeMethodToBeTested()
{
  var dateTimeNow = DateTime.Now;
  if (dateTimeNow.Month == 4 && dateTimeNow.Day == 6)
  {
    //do something for the new tax year.
  }
  else
  {
    //do something for the current tax year.
  }
}

The problem is: how can we test different dates so make sure the correct tax year dependent processing takes place? We clearly need the ability to control the date being used. We could do this by creating a wrapper class for DateTime, but I prefer in this simple case to just use a Func.

The test code becomes:

[TestFixture]
public class StubbingDateTimeNowTest
{
  [Test]
  public void TestNewTaxTear()
  {
    var stubbingDateTimeNow=new StubbingDateTimeNow(() => new DateTime(2012,4,6)); //send in a Func to return the date I want to test
    stubbingDateTimeNow.SomeMethodNowTested();
    //Asserts to check correct processing took place
  }

  [Test]
  public void TestCurrentTaxTear()
  {
    var stubbingDateTimeNow=new StubbingDateTimeNow(() => new DateTime(2012,3,6)); //send in a Func to return the date I want to test
    stubbingDateTimeNow.SomeMethodNowTested();
    //Asserts to check correct processing took place
  }
}

And the code under test needs a constructor to enable me to inject in the Func that creates a DateTime object. The default constructor that would be called in production simply provides a Func that will return DateTime.Now when called:

public class StubbingDateTimeNow
{
  private readonly Func<DateTime> getCurrentDateTime;

  public StubbingDateTimeNow(Func<DateTime> getCurrentDateTime)
  {
    this.getCurrentDateTime = getCurrentDateTime;
  }

  public StubbingDateTimeNow() : this(() => DateTime.Now) {} //default constructor provides a Func to return DateTime.Now

  public void SomeMethodNowTested()
  {
     var dateTimeNow = getCurrentDateTime();
     if (dateTimeNow.Month == 4 && dateTimeNow.Day == 6)
     {
       //do something for the new tax year.
     }
     else
     {
       //do something for the current tax year.
     }
  }
}

Posted in .NET, Test Driven Development | Tagged: , , | Leave a Comment »

Cloning an Object

Posted by Kash Farooq on June 15, 2012

I thought I’d post this code as I frequently find myself needing it on various projects.

Making a deep copy clone of an object:

public static T CloneObject<T>(T objectToClone) {
  using (var memoryStream = new MemoryStream()) {
    var xmlSerializer = new XmlSerializer(typeof (T));
    xmlSerializer.Serialize(memoryStream, objectToClone);
    memoryStream.Position = 0;
    return (T) xmlSerializer.Deserialize(memoryStream);
  }
}

Basically, serialize an object to memory and then deserialize it into a completely different new object, breaking the memory reference.

Posted in .NET | Tagged: , , | Leave a Comment »

MongoDB in C#: Mapping IDs

Posted by Kash Farooq on March 4, 2012

In my previous post about C# and MongoDB, I polluted my domain model with a MongoDB type:

public class Movie
{
  public BsonObjectId Id { get; set; }
  public string Title { get; set; }
  public string Year { get; set; }

  etc
}

When you Insert a document into MongoDB using the C# driver, the driver needs to check to see if the Id has a value. It assigns one if it doesn’t. The above code worked because I used a MongoDB C# driver ID type – the driver could work out what my ID property is. But I don’t really want to use BsonObjectId in this class – it ties me to MongoDB. Instead, you can use a built-in .NET type for the ID property and tell the MongoDB C# driver about it.

First, let’s change the type of the Id property. I’ve gone for a string but there are other types you could use:

public class Movie
{
  public string Id { get; set; }
  public string Title { get; set; }
  public string Year { get; set; }

  etc
}

Now, you need to map that property. I’m doing this code in an NUnit test, so I’m going to do the mapping in the TestFixtureSetUp:

[TestFixtureSetUp]
public void TestFixtureSetUp()
{
  BsonClassMap.RegisterClassMap<Movie>(cm => {
                                              cm.AutoMap();
                                              cm.SetIdMember(cm.GetMemberMap(x => x.Id).SetIdGenerator(StringObjectIdGenerator.Instance));
                                             }
                                       );
}

So, I’ve told the MongoDB C# driver that the ID column is Movie.Id and that it needs to use its built in StringObjectIdGenerator to generate IDs.

There are several ID generators built into the driver:

  • BsonObjectIdGenerator
  • CombGuidGenerator
  • GuidGenerator
  • NullIdChecker
  • ObjectIdGenerator
  • StringObjectIdGenerator
  • ZeroIdChecker<T>

Read the CSharp Driver Serialization Tutorial for more information about these generators and mapping them to properties.

Posted in .NET, NoSQL | Tagged: , , , | Leave a Comment »

Playing with FluentAssertions

Posted by Kash Farooq on February 23, 2012

I thought I’d try a FluentAssertions – a different way of doing asserts in Unit Tests.

As the name of the library suggests, your assertion code is fluent. i.e. methods are chained.

Some examples.

A simple assert:

person.YearOfBirth.Should().Be(1945);

To check a list has the correct number of elements:

personList.Should().HaveCount(10);

To ensure that a list has elements in a certain order:

IEnumerable<int> positions = personList.Select(x => x.Rank);
positions.Should().ContainInOrder(new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});

There are lots of helper methods and the lots of examples in the on-line documentation.

I quite like it and have been using it on a project.

And it’s not just the assertion style that I like.

The thing that really impressed me was when one of my tests failed. In my assert I was comparing two strings. I clearly should have done a .Trim() on my string under test, but I forgot. And here is the error I saw in my test runner window:


Expected string to be
"John Smith", but it has unexpected whitespace at the end.

How useful is that! No more “the string differs at position 45”.

Posted in .NET, Test Driven Development | Tagged: , , | Leave a Comment »

Getting started with MongoDB in C#

Posted by Kash Farooq on February 18, 2012

I thought I’d play with NoSQL. There are lots of implementations to choose from, but I’ve decided to start with MongoDB. Especially after seeing the impressive list of real-life production MongoDB deployments.

The MongoDB server and data structure is organised as follows:

  • A Mongo server holds a set of databases
  • A database holds a set of collections
  • A collection holds a set of documents
  • A document is a set of fields
  • A field is a key-value pair
  • A key is a string
  • A value is a
    • strings, integers, etc.
    • another document
    • an array of values

Right. Let’s get started. First, download the two things you’ll need to start developing MongoDB apps in .NET: the database software and the C# driver.

I also recommend you download a PDF of the documentation. It is available as a MongoDB docs daily build. This PDF contains everything: set-up instructions, tutorials, advice and language specific driver documentations.

Use the Windows Quick Start to get going and test your MongoDB server with the administrative JavaScript shell client. I also advise you go through the tutorial – it walks you through more complex examples using the administrative shell client. As noted above, both these guides are in the MongoDB Docs PDF.

Install the C# driver by just running the MSI. It installs to C:\Program Files (x86)\MongoDB.

Create a .NET project and add assembly references to MongoDB.Driver.dll and MongoDB.Bson.dll. I created NUnit integration tests to test MongoDB.

First, I created a class that I wanted to store as a MongoDB document:

public class Movie
{
  public BsonObjectId Id { get; set; }
  public string Title { get; set; }
  public string Year { get; set; }
  public List<string> Actors { get; set; }

  public void AddActor(string actor)
  {
    if (Actors == null)
    {
      Actors = new List<string>();
    }
    Actors.Add(actor);
  }
}

Things to note in this class:

  • I’ve used the type BsonObjectId. To get up and running quickly, I basically told the MongoDB C# driver which property to use as an ID. You don’t have to do this. To see how to remove MongoDB C# driver specific types from your domain object, see my Mapping IDs post.
  • I’ve included a generic list – I wanted to see how the C# driver copes with this, how MongoDB stores this data, and how we can search for documents using this data.
  • I had to make the Actors list public, otherwise the C# driver wouldn’t store it. Perhaps there is a way to force the driver to store it without making it public? Something to research.

Next, let’s open a connection to a database and insert some data. I’m orchestrating the prerequisites for my test through a NUnit Setup method the connects to the database, empties the collection and inserts some fresh data:

private MongoServer server;
private MongoDatabase moviesDatabase;

[SetUp]
public void SetUp()
{
  Connect();
  Clean();
  InsertData();
}

private void Connect()
{
  server = MongoServer.Create();
  moviesDatabase = server.GetDatabase("movies_db");
}

As you can see, the connect method didn’t use any information such as connection strings, usernames, etc. It just calls Create. If you don’t provide any parameters it connects to a default instance of MongoDB on localhost. If you’ve changed any of the default settings, you’ll need a connection string.

The GetDatabase method gets me an instance of the “movies” database if it exists, or lazily creates it if it doesn’t (i.e. it won’t actually be created until you save some data to it).

The Clean() method is just used to empty the collection each time a test runs. I’m calling the RemoveAll method to empty all elements from the movies_collection:

private void Clean()
{
  var moviesCollection = moviesDatabase.GetCollection<Movie>("movies_collection");
  moviesCollection.RemoveAll();
}

Now let’s add some data to the movies_collection and save it to the movies_db:

private void InsertData()
{
  //Create some data
  var movie1 = new Movie {Title = "Indiana Jones and the Raiders of the Lost Ark", Year = "1981"};
  movie1.AddActor("Harrison Ford");
  movie1.AddActor("Karen Allen");
  movie1.AddActor("Paul Freeman");

  var movie2 = new Movie {Title = "Star Wars: Episode IV - A New Hope", Year = "1977"};
  movie2.AddActor("Mark Hamill");
  movie2.AddActor("Harrison Ford");
  movie2.AddActor("Carrie Fisher");

  var movie3 = new Movie {Title = "Das Boot", Year = "1981"};
  movie3.AddActor("Jürgen Prochnow");
  movie3.AddActor("Herbert Grönemeyer");
  movie3.AddActor("Klaus Wennemann");

  //Insert the movies into the movies_collection
  var moviesCollection = moviesDatabase.GetCollection<Movie>("movies_collection");
  moviesCollection.Insert(movie1);
  moviesCollection.Insert(movie2);
  moviesCollection.Insert(movie3);
}

So, we’ve created/opened a database called movie_db and insert some data into a movies_collection. Let’s check it’s there – get the collection and check that there are 3 movies in it.

[Test]
public void ShouldFindThreeMoviesInTheCollection()
{
  var moviesCollectionRetrieved = moviesDatabase.GetCollection<Movie>("movies_collection");
  Assert.That(moviesCollectionRetrieved.Count(), Is.EqualTo(3));
}

Now let’s do a query on the movie data. Let’s look for movies that were released in 1981, i.e. perform a query based on one of the keys – in this case, the “Year” key:

[Test]
public void ShouldFindTwoMoviesThatWereMadeIn1981()
{
  var moviesCollectionRetrieved = moviesDatabase.GetCollection<Movie>("movies_collection");

  QueryComplete findMoviesMadeIn1981Query = Query.EQ("Year", "1981");
  var moviesFound = moviesCollectionRetrieved.FindAs<Movie>(findMoviesMadeIn1981Query);

  Assert.That(moviesFound.Count(), Is.EqualTo(2));
  Assert.That(moviesFound.Count(movie => movie.Title == "Das Boot"), Is.EqualTo(1));
  Assert.That(moviesFound.Count(movie => movie.Title == "Indiana Jones and the Raiders of the Lost Ark"),Is.EqualTo(1));
}

Note that I used the generic version FindAs method – to get the C# driver to create movie objects from the MongoDB documents.

You can also very easily perform queries based on values stored in lists. Here, for example, I am looking for documents that contain a certain value in the Actors list – let’s look for movies that Harrison Ford has been in:

[Test]
public void ShouldFindTwoMoviesThatHarrisonFordHasBeenIn()
{
  var moviesCollectionRetrieved = moviesDatabase.GetCollection<Movie>("movies_collection");

  var findMoviesWithHarrisonFordInThem = Query.EQ("Actors", "Harrison Ford");
  var moviesFound = moviesCollectionRetrieved.FindAs<Movie>(findMoviesWithHarrisonFordInThem);
  Assert.That(moviesFound.Count(), Is.EqualTo(2));
  Assert.That(moviesFound.Count(movie => movie.Title == "Star Wars: Episode IV - A New Hope"),Is.EqualTo(1));
  Assert.That(moviesFound.Count(movie => movie.Title == "Indiana Jones and the Raiders of the Lost Ark"),Is.EqualTo(1));
}

Very neat.

In the code above I’ve been using Count(). That does not mean that the C# driver supports delayed execution and LINQ. The official statement is: “Version 1.0 of the official C# driver does not yet support LINQ”. In fact, the documentation states that for the following code, the query is sent to the server twice (once for FirstOrDefault and once for LastOrDefault)


var query = Query.EQ("author", "Ernest Hemingway");
var cursor = books.Find(query);
var firstBook = cursor.FirstOrDefault(); //query executed twice on the server
var lastBook = cursor.LastOrDefault(); //once for each of these IEnumerable<T> extension methods.

Finally, let’s look at how the data has been stored using the administrative JavaScript shell client, mongo.exe.

With the client, I’ll connect to the server, switch to the movies database and then display all the documents in the movies_collection:


MongoDB shell version: 2.0.2
connecting to: test
> use movies_db
switched to db movies_db
> db.movies_collection.find().forEach(printjson);
{
 "_id" : ObjectId("4f3f82a1d5c8851b60430b9a"),
 "Title" : "Indiana Jones and the Raiders of the Lost Ark",
 "Year" : "1981",
 "Actors" : [
 "Harrison Ford",
 "Karen Allen",
 "Paul Freeman"
 ]
}
{
 "_id" : ObjectId("4f3f82a1d5c8851b60430b9b"),
 "Title" : "Star Wars: Episode IV - A New Hope",
 "Year" : "1977",
 "Actors" : [
 "Mark Hamill",
 "Harrison Ford",
 "Carrie Fisher"
 ]
}
{
 "_id" : ObjectId("4f3f82a1d5c8851b60430b9c"),
 "Title" : "Das Boot",
 "Year" : "1981",
 "Actors" : [
 "J├╝rgen Prochnow",
 "Herbert Gr├Ânemeyer",
 "Klaus Wennemann"
 ]
}
>

Posted in .NET, NoSQL | Tagged: , , , | Leave a Comment »

Calculating Pi in C# part 2 – using the .NET 4 BigInteger class

Posted by Kash Farooq on July 23, 2011

In my previous post, I used a couple of algorithms to calculate Pi. With my implementation of the algorithms, to get to a precision of just 6 decimal places took well over a million iterations and over 3 seconds.

Clearly I was doing something wrong.

A few Google searches later I found this implementation by Julian M Bucknall. In this implementation, Julian creates a BigNumber class to handle the fact that, before .NET 4, there was no way to handle numbers to many digits of precision. His class uses  fixed point arithmetic for storing data and performing calculations – effectively it works in base 4,294,967,296 (which is 232).

As .NET does now contain a BigInteger class (in .NET 4’s System.Numerics), I started searching for C# implementations that used this class. I couldn’t find anything in C#, but I did find a Java implementation that used a BigInteger class.

So, I decided to port it to C#, amending the BigInteger usages to match the .NET implementation syntax.

The formula used is the one that John Machin devised in 1706:

John Machin's Pi formulaSo, here is the .NET port of the Java implementation  – it includes a method called InverseTan to be used in the above formula, which I won’t even try to understand at the moment. I’m just doing the port!

public class PiJavaPort {
    public static BigInteger InverseTan(int denominator, int numberOfDigitsRequired) {
        int demonimatorSquared = denominator*denominator;

        int degreeNeeded = GetDegreeOfPrecisionNeeded(demonimatorSquared, numberOfDigitsRequired);

        BigInteger tenToNumberPowerOfDigitsRequired = GetTenToPowerOfNumberOfDigitsRequired(numberOfDigitsRequired);

        int c = 2*degreeNeeded + 1;
        BigInteger s = BigInteger.Divide(tenToNumberPowerOfDigitsRequired, new BigInteger(c)); // s = (10^N)/c
        for (int i = 0; i < degreeNeeded; i++) {
            c = c - 2;
            var temp1 = BigInteger.Divide(tenToNumberPowerOfDigitsRequired, new BigInteger(c));
            var temp2 = BigInteger.Divide(s, new BigInteger(demonimatorSquared));
            s = BigInteger.Subtract(temp1, temp2);
        }
        Console.WriteLine("Number of iterations=" + degreeNeeded);

        // return s/denominator, which is integer part of 10^numberOfDigitsRequired times arctan(1/k)
        return BigInteger.Divide(s, new BigInteger(denominator));

    }

    private static int GetDegreeOfPrecisionNeeded(int demonimatorSquared, int numberOfDigitsRequired) {
        //the degree of the Taylor polynomial needed to achieve numberOfDigitsRequired
        //digit accuracy of arctan(1/denominator).
        int degreeNeeded = 0;

        while ((Math.Log(2*degreeNeeded + 3) + (degreeNeeded + 1)*Math.Log10(demonimatorSquared))
                                                <= numberOfDigitsRequired*Math.Log(10)) {
            degreeNeeded++;
        }
        return degreeNeeded;
    }

    private static BigInteger GetTenToPowerOfNumberOfDigitsRequired(int numberOfDigitsRequired) {
        var tenToNumberOfDigitsRequired = new BigInteger(1);

        //  The following loop computes 10^numberOfDigitsRequired
        for (var i = 0; i < numberOfDigitsRequired; i++) {
            tenToNumberOfDigitsRequired = BigInteger.Multiply(tenToNumberOfDigitsRequired, new BigInteger(10));
        }
        return tenToNumberOfDigitsRequired;
    }
}

Finally, we need a method to put it all together – we need to implement the Machin formula:

public static string Calculate(int numberOfDigitsRequired)
{
    numberOfDigitsRequired += 8; //  To be safe, compute 8 extra digits, to be dropped at end. The 8 is arbitrary

    var a = BigInteger.Multiply(InverseTan(5, numberOfDigitsRequired), new BigInteger(16)); //16 x arctan(1/5)
    var b = BigInteger.Multiply(InverseTan(239, numberOfDigitsRequired), new BigInteger(4)); //4 x arctan(1/239)

    BigInteger pi = BigInteger.Subtract(a, b);

    var piAsString = BigInteger.Divide(pi, new BigInteger(100000000)).ToString();
    var piFormatted = piAsString[0]+"."+piAsString.Substring(1,numberOfDigitsRequired-8);
    return piFormatted;
}

Now to test the two implementations for performance – my Java port above vs. Julian M Bucknall implementation using his own BigNumber class.

First, my Java Port using .NET’s numerics:

Precision = 1000 digits
Number of iterations needed = 3659
Elapsed Milliseconds = 96

Not bad! Much better than 1 million plus iterations for 6 decimal places that my pathetic attempt took!

Now to Julian M Bucknall’s implementation (using his own BigNumber class):

Precision = 1000 digits
Number of iterations needed = 1603
Elapsed Milliseconds = 77

We have a winner.

Julian’s BigNumber class is optimised for this calculation – it can only divide a BigNumber by an integer. You cannot divide a BigNumber by another BigNumber. He states that if he had to implement such functionality he “would have discretely dropped the entire project”!

BigInteger does not have this limitation (and this functionality is used in the port).

Posted in .NET, Algorithms | Tagged: , , , | Leave a Comment »