Wednesday, February 1, 2012

Arg<T>? ARGH!!!

Rhino.Mocks has a great syntax for setting argument constraints since version 3.5 using inline constrains (you can read more about it here).

I recently came across two interesting cases that I think are worth sharing.

While the Arg<T> class provides a more elegant syntax, it sometimes leads to code such as this:

   1: [Test]
   2: public void Test()
   3: {
   4:     var stub = MockRepository.GenerateStub<IDoSomething>();
   5:     stub.Stub(s => s.DoSomething(Arg<IList<ICustomer>>.Matches(list=>list[1].FirstName.Equals("Mike") && list[1].Age == 20);)).Return(1);
   6:  
   7:     var youngerMike = MockRepository.GenerateStub<ICustomer>();
   8:     youngerMike.Stub(s => s.Age).Return(20);
   9:     youngerMike.Stub(s => s.FirstName).Return("Mike");
  10:  
  11:     var olderMike = MockRepository.GenerateStub<ICustomer>();
  12:     olderMike.Stub(s => s.Age).Return(40);
  13:     olderMike.Stub(s => s.FirstName).Return("Mike");
  14:  
  15:     var customers = new[] { olderMike, youngerMike };
  16:     var result = stub.DoSomething(customers);
  17:  
  18:     Assert.That(result, Is.EqualTo(1));
  19: }

That whole “Arg<IList<ICustomer>>.Matches” thing? Not a pretty sight, and that’s without having multiple parameters with multiple constraints…


Since Arg<T> returns a T, I figured I can use a local variable to hold the constraint, like this:



   1: var listWithYoungerMikeAsSecond = Arg<IList<ICustomer>>.Matches(list=>list[1].FirstName.Equals("Mike") && list[1].Age == 20);
   2: stub.Stub(s => s.DoSomething(listWithYoungerMikeAsSecond)).Return(1);

Still works and the tests is a little clearer (The code snippet might look as messy in this post, but it makes the difference inside VS).


So, what’s the problem?


These are the two examples that got me, well, a little frustrated. In the first, I grouped similar code lines together, since I like the pretty colors:



   1: var youngerMikeStub = MockRepository.GenerateStub<IDoSomething>();
   2: var olderMikeStub = MockRepository.GenerateStub<IDoSomething>();
   3:  
   4: var listWithYoungerMikeAsSecond = Arg<IList<ICustomer>>.Matches(list => list[1].FirstName.Equals("Mike") && list[1].Age == 20);
   5: var listWithOlderMikeAsSecond = Arg<IList<ICustomer>>.Matches(list => list[1].FirstName.Equals("Mike") && list[1].Age == 40);
   6:  
   7: youngerMikeStub.Stub(s => s.DoSomething(listWithYoungerMikeAsSecond)).Return(1);
   8: olderMikeStub.Stub(s => s.DoSomething(listWithYoungerMikeAsSecond)).Return(1);

Running this test throws the following exception at line 7 in the above:

System.InvalidOperationException: Use Arg<T> ONLY within a mock method call while recording. 1 arguments expected, 2 have been defined.

This was cause because we defined two Arg<T> constraints and actually using only one of them for the first stub method call!


The second example is this:



   1: [Test]
   2: public void Test()
   3: {
   4:     var listWithYoungerMikeAsSecond = Arg<IList<ICustomer>>.Matches(list=>list[1].FirstName.Equals("Mike") && list[1].Age == 20);
   5:  
   6:     var stub = MockRepository.GenerateStub<IDoSomething>();
   7:     stub.Stub(s => s.DoSomething(listWithYoungerMikeAsSecond)).Return(1);
   8:  
   9:     var youngerMike = MockRepository.GenerateStub<ICustomer>();
  10:     youngerMike.Stub(s => s.Age).Return(20);
  11:     youngerMike.Stub(s => s.FirstName).Return("Mike");
  12:  
  13:     var olderMike = MockRepository.GenerateStub<ICustomer>();
  14:     olderMike.Stub(s => s.Age).Return(40);
  15:     olderMike.Stub(s => s.FirstName).Return("Mike");
  16:  
  17:     var customers = new[] { olderMike, youngerMike };
  18:     var result = stub.DoSomething(customers);
  19:  
  20:     Assert.That(result, Is.EqualTo(1));
  21: }

And the tests fails since the method returns 0 and not 1 - I declared the Arg before the mock itself, now running this test doesn’t match our expectation although they’re clearly met.


Just a little frustrated


Inline is INLINE!


Yes, I know they’re called INLINE constraints, but still, it took me a while to actually understand that Arg<T> isn’t just generating constraints, it’s actually coupled to the current mocked object.


What does it mean? It means that we should use Arg<T> inside the Stub method itself or right before it, but ONLY after generating the stub/mock and ONLY the specific Args we’re using in the following Stub method.


Mock away.

Friday, May 6, 2011

Prioritize your workplace expectations

In less than two months I’ll be leaving my current position, which made me dust off my CV and sniff around for some new job offers. I came across an old post that a friend wrote about the ideal workplace and it made me think about my priorities. I scratched my head for a while and this is what I came up with (obviously, it’s totally subjective):

Must have’s:

  • Belief in the product’s potential and need.
  • A team of talented and productive developers that I can learn from.
  • An agile approach and constant awareness for improving.
  • FUN, a social environment is much more satisfying and motivating.
  • Coffee.                            
  • Seriously - Coffee.

Nice to have’s:

  • Close to where I live (luckily, in Tel-Aviv it isn’t that hard to find).
  • Be one of the first 10 employees in the company.
  • Highest possible salary, or options in a small startup that’s hoping to sell.
  • An option to move up (Developer –> Team leader –> Architect…)

Not even an options:

  • Outsourcing – I want to be paid by the same person I work for.
  • Low tech (a Bank’s IT department and such).
  • Being stuck more than an hour in traffic each direction every day.

Doesn’t really matter:

  • Staying in your “comfort zone” (.Net vs. Python, windows vs. unix, etc.).
  • Starting from scratch vs. working on an existing product.
  • Working 9 to 17 vs. working dusk till dawn (as long as I like it of course).
  • Free company goodies (phone \ laptop \ drink machine \ etc.), it can’t hurt though!

As for the interview itself - we’re often too busy trying to impress our interviewers that we forget that our impression of them is just as important. Keep in mind that an interview is a two way conversation – come prepared with questions of your own, and make sure you ask them.

If you believe that you’re a good software developer \ manager and have something to show for it, you should be confident in yourself and expect what you deserve.

P.S

If you think the same and you’re hiring in Israel, feel free to contact me via email at matanzg@gmail.com or via Facebook.

Monday, April 25, 2011

NHibernate Tutorial, Part 3 – Configuration

This is part 3 of my NHibernate tutorial, make sure to start from part 1.

Now that we have a mapped model, it’s time to configure the classes that will actually do the hard work. let’s review them:

The Session

The session (more precisely the ISession interface) is our primary API for using NHibernate. It exposes methods for saving, deleting, updating and querying entities. It’s disposable and cheap to create, although deciding when to create or dispose a session is a subject of it’s own, more on which I’ll elaborate later. What’s important to remember for now is that opening a session isn’t equivalent to opening a database connection – the connections are being pooled for us by the session factory, so when we hold a session open an underlying database connection isn’t necessarily being put on hold for us. Also, a session isn’t thread-safe and should be managed accordingly as needed by your application’s architecture (again, more on that later).

The Transaction

NHibernate has it’s own ITransaction interface that doesn’t comply to System.Transactions namespace, for better or worse. managing the transaction goes hand in hand with managing the session, after all an atomic unit of work should be wrapped in a single transaction and we perform those actions on our session. I’ll explain a little more later about that, but it’s important to remember that opening a transaction (unlike opening a session) IS blocking a database connection – that’s why we need to make them as atomic as possible.

The Session Factory

The session factory is an object that’s configured once per database at the application initialization. It knows which database we use, what our domain looks like, how to handle cache, etc.. The session factory (as it’s name reflects) is responsible for creating sessions throughout our application, while managing the connection pool to the database. It’s thread safe and should be accessible throughout our application. It’s also very expensive to create, for obvious reasons.

Configuring the session Factory

NHibernate supports built it configuration via xml, an example can be found here. Also, stating with NHibernate 3, NHibernate supports configuration via code using the NHibernate.Cfg.Loquacious namespace, more on that can be found here. As I said before, I rather work with FNH with provides mappings and configuration via code, so from here on that’s what we’ll be focusing on.

Yawn. Let’s write some code.

Using the Server Explorer, create a new database (I’m assuming you have SQL Server express 2008 on your machine):db-step-1

db-step-2

Create a new Console Application and use Nuget to add a library package reference to FluentNHibernate. Then add an app.config file and add the following text in it:

<connectionStrings>
    <add name="DbConnection" 
         connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Tutorial;Integrated Security=True;Pooling=False"/>
  </connectionStrings>

Now paste the following code to Program.cs:



   1: using System;
   2: using Entities;
   3: using FluentNHibernate.Cfg;
   4: using FluentNHibernate.Cfg.Db;
   5: using Mapping;
   6: using NHibernate;
   7: using NHibernate.Cfg;
   8: using NHibernate.Tool.hbm2ddl;
   9:  
  10: namespace ConsoleApp
  11: {
  12:     class Program
  13:     {
  14:         private static ISessionFactory _sessionFactory;
  15:  
  16:         static void Main(string[] args)
  17:         {
  18:             Person person;
  19:  
  20:             using (ISession session = OpenSession())
  21:             using (ITransaction tx = session.BeginTransaction())
  22:             {
  23:                 person = new Person { Name = "Matan" };
  24:                 session.Save(person);
  25:                 session.Flush();
  26:                 tx.Commit();
  27:             }
  28:  
  29:             using (ISession session = OpenSession())
  30:             using (ITransaction tx = session.BeginTransaction())
  31:             {
  32:                 var newPerson = session.Get<Person>(person.Id);
  33:                 Console.WriteLine(newPerson.Name);
  34:             }
  35:         }
  36:  
  37:         private static ISession OpenSession()
  38:         {
  39:             if (_sessionFactory == null)
  40:             {
  41:                 _sessionFactory = Fluently.Configure()
  42:                     .Database(MsSqlConfiguration.MsSql2008.ShowSql()
  43:                     .ConnectionString(cfg => cfg.FromConnectionStringWithKey("DbConnection")))
  44:                     .Mappings(cfg => cfg.FluentMappings.AddFromAssemblyOf<StoreMap>())
  45:                     .ExposeConfiguration(AddConfig)
  46:                     .BuildSessionFactory();
  47:             }
  48:  
  49:             return _sessionFactory.OpenSession();
  50:         }
  51:  
  52:         private static void AddConfig(Configuration cfg)
  53:         {
  54:             new SchemaExport(cfg).Create(true, true);
  55:         }
  56:     }
  57: }

Finally, we have some entities flying around! If you run the code you can see the SQL (both DDL and DML) in the output window of your application, also the data should appear in your database.


We created a session factory (on the first session request), opened a session and a transaction and used them to persist a new Person entity. Then we created a new session (and transaction) and queried for a person with a given id. We then print out the new entity’s name to make sure it’s indeed our entity.


Let’s go over the interesting parts again:



   1: _sessionFactory = Fluently.Configure()
   2:     .Database(MsSqlConfiguration.MsSql2008.ShowSql()
   3:     .ConnectionString(cfg => cfg.FromConnectionStringWithKey("DbConnection")))
   4:     .Mappings(cfg => cfg.FluentMappings.AddFromAssemblyOf<StoreMap>())
   5:     .ExposeConfiguration(AddConfig)
   6:     .BuildSessionFactory();

We start by FNH’s Fluently.Configure() methods and then use:



  1. The Database method, used to define that we’re using SQL Server 2008, and supply two other settings:

    1. ShowSql() - sets NHibernate to print to the default output every SQL command that’s being executed by a session.
    2. ConnectionString – set to be taken from our app.config under the name “DbConnection”.

  2. Next, the Mappings method where we point our configuration to our ClassMaps. I chose to use all of the ClassMap’s in the mappings assembly, but you can add them one by one if you’d like. Notice that other than FluentMappings we can also add HbmMappings (read more here) or AutoMappings (read more here), I’d rather use FluentMappings.
  3. Next, the ExposeConfiguration allows us to perform extra custom configuration on our underlying IConfiguration object just before it becomes an ISessionFactory. We’ll get there soon, but remember that this is where we can add custom NHibernate configuration, such as listeners and interceptors.
  4. Finally, a call to BuildSessionFactory wraps it all up and gives us an ISessionFactory, ready for work!

Moving on:



   1: private static void AddConfig(Configuration cfg)
   2: {
   3:     new SchemaExport(cfg).Create(true, true);
   4: }

As I said, this is our chance to add our custom configuration to the session factory. I’m using a SchemaExport object to tell the session factory that it should generate and export the SQL’s DDL commands upon initialization. Important Note – Some systems use NHibernate to map an existing database, while others create a brand new one for a new system – while SchemaExport is obviously very useful in the development process, you should still manually export changes to your integration and production environments – be careful not to use SchemaExport on a database you DON’T WANT TO DROP.


Lastly:



   1: using (ISession session = OpenSession())
   2: using (ITransaction tx = session.BeginTransaction())
   3: {
   4:     person = new Person { Name = "Matan" };
   5:     session.Save(person);
   6:     session.Flush();
   7:     tx.Commit();
   8: }

We use the session factory’s OpenSession method to start a new session, we that use the session to explicitly begin a new transaction. If I hadn’t opened a transaction explicitly, the session would have opened one implicitly and committed it when required. Keep in mind that once you open a transaction, unless you commit it yourself it’ll be rolled-back. The session.Flush method isn’t required here since it precedes a commit and that would have triggered a flush automatically, but remember that:



  • The session will try to make the minimum possible database requests to achieve maximum efficiency. When using Session.Save you only add your entity to the session’s list of references (AKA first level cache), the actual insert command will only be executed when a flush is called (either by the user or by the active transaction). UNLESS… we use a database mechanism to generate primary keys (such as SQL Server’s Identity or Oracle’s sequence) which forces our session to go directly to the database on every Save command – not very efficient, is it? There are better ways, read more here. But let’s keep it simple for now.
  • The database understand transactions, and only transactions – even if you only query data. If you won’t open one yourself it’ll be opened implicitly and that may lead to performance issues, running 3 different Get methods without opening a transaction could lead to 3 different transactions. As a best practice, make sure to begin a transaction explicitly and commit it when you’re done with it – even if you only run queries! More on session and transaction management later on.

Well, we now have a session factory that persists our entities using our mappings, but what else can we do with a session? Find out in the next part – Session and Transaction.

Sunday, April 24, 2011

NHibernate Tutorial, Part 2 – Modeling Our Domain

This is part 2 of my NHibernate tutorial, make sure to start from part 1.

It’s time to use NHibernate to model our entities.

What are the different ways to model an entity?

NHibernate originally supported two means of entity modeling (both of which are not ideal):

  • Xml – using hbm.xml files to define mappings via the nhibernate-mapping-2.0.xsd schema. Xml files on the other hand, are, well, Xml files – they don’t compile and the intellisense is poor. (AND I JUST HATE XML FILES! there, I’ve said it! Meta programming is great in theory but frustrating in practice).
  • Attributes – using .Net Attributes from NHibernate.Mapping.Attributes. the attributes create clutter in classes and they couple our entities to NHibernate since unlike Java’s JPA, .Net doesn’t have a common persistence API meaning we have to use NHibernates attributes directly.

Luckily, we now have better alternatives. I’m going to use FluentNHibernate since I really like the simple and elegant API. An alternative is ConfORM, which is integrated in the NHibernate 3.2 release.

Using Fluent NHibernate

Let’s rebuild our domain from scratch, this time even simpler:

Create a new class library named “Entities”, add the following classes:

public class Store
{
    public Store()
    {
        Branches = new HashSet<Branch>();
    }
 
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual Person Contact { get; set; }
    public virtual ICollection<Branch> Branches { get; set; }
}
 
public class Branch
{
    public virtual int Id { get; set; }
    public virtual Store Store { get; set; }
    public virtual Person Manager { get; set; }
}
 
public class Person
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}


It’s important to notice that all of our classes’ properties and methods must be virtual, that’s because of NHibernates use of proxies for lazy loading, but more on that later. For now, you can just use my vprop snippet to save time.



FluentNHibernate (from now on, FNH) maps entities using ClassMaps, which on initialization generate xml that’s similar to NHibernates classic hbm files.



Create a new class library named “Mapping”, since this is where we first use NHibernate we’ll use Nuget to get the dependencies (install SP1 if you haven’t already, it’s in there):





  • Right click your project –> “Add Library Package Reference”nuget-step-1

  • Search online for FluentNHibernate and install it. notice it depends on NHibernate, which itself depends on other packages: nuget-step-2

  • Follow this post to make sure Nuget keeps your dependencies up to date without having to check them into you source control.


Let’s start with mapping our Person class, since it’s the simplest of the three. Add a new class to the mapping project named it PersonMap, it should look something like this:




 

   1: using Entities;
   2: using FluentNHibernate.Mapping;
   3:  
   4: namespace Mapping
   5: {
   6:     public class PersonMap : ClassMap<Person>
   7:     {
   8:         public PersonMap()
   9:         {
  10:             Id(p => p.Id).Column("id").GeneratedBy.Identity();
  11:             Map(p => p.Name).Column("name").Not.Nullable().Length(25);
  12:         }
  13:     }
  14: }


Let’s see what we have here:





  • On line 6 you can see we inherit from FNH’s ClassMap<> which makes this class a fluent mapper for Person.

  • On line 10 we define the class’s primary key using a lambda expression, making it refactor friendly. We also define SqlServer identity as the generator for the primary key and “id” as the database column name (later, we’ll use a convention for that, but let’s keep it simple for now). If we don’t define a column name it’ll be the property name by default, and if we don’t define a generator it’s native by default. Read some more here (keep in mind that I use Identity for simplicity, it’s probably NOT the best generator since it has to use the database to generate a new PK).

  • On line 11, again using a lambda expression, we define the Name property as a not nullable, 25 chars long column.


Moving on to the Store map:




 

   1: using Entities;
   2: using FluentNHibernate.Mapping;
   3:  
   4: namespace Mapping
   5: {
   6:     public class StoreMap : ClassMap<Store>
   7:     {
   8:         public StoreMap()
   9:         {
  10:             Id(s => s.Id).Column("id").GeneratedBy.Identity();
  11:             Map(s => s.Name).Column("name").Not.Nullable().Length(25);
  12:  
  13:             References(s => s.Contact);
  14:  
  15:             HasMany(s => s.Branches)
  16:                 .AsSet()
  17:                 .Inverse()
  18:                 .Cascade.SaveUpdate();
  19:         }   
  20:     }
  21: }
Let’s see what we have that’s new:



  • Using the References method on line 13 we define Contact as a reference, this will result in a Person foreign key in the Store’s table. I can specify the foreign key’s column name, but the default will be something like Contact_id.

  • Using the HasMany method we define that we have many branches, this will result in a foreign key of Store in the Branches table. We also define:



    • AsSet – the default behavior is AsBag, while a One-To-Many relation is actually more similar to a Set. Read more here.

    • Inverse – When defining a one-to-many relation, an update to the database can result in duplicate update statements, since both the “Many” entity and the “One” entity take responsibility for the relation and execute update. Declaring “Inverse” on the relation means “I’m not responsible for updating it”. Usualy the “Many” side is responsible since it holds the foreign key, in our case the Branch will have a reference to Store and that part of the relation will be responsible for updating it.

    • Cascade – defining the cascade as SaveUpdate means that when saving a new Store or updating an existing one will result in an attempt to save or update the branches in it’s branches collection. Read more here.


Lastly, let’s map our Branch entity:




 

   1: using Entities;
   2: using FluentNHibernate.Mapping;
   3:  
   4: namespace Mapping
   5: {
   6:     public class BranchMap : ClassMap<Branch>
   7:     {
   8:         public BranchMap()
   9:         {
  10:             Id(b => b.Id).Column("id").GeneratedBy.Identity();
  11:  
  12:             References(b => b.Manager);
  13:             References(b => b.Store);
  14:         }
  15:     }
  16: }


Finally, nothing new here. Smile



The previous map will comply to the following database schema:



erd



But for you guys to see it for yourselves, you’ll have to configure a SessionFactory, more on that in the next part – Configuration.