Web service contracts and AutoMapper

 

I’ve recently had a great experience using AutoMapper on a project (the project is iMeta’s solution to managing information used to settle trades, Assassin).

I used it to map from my service contract back into the domain model of our application.

There’s a bunch of really good reasons (e.g. ease of use and protecting people from change) why a service contract is not the same as your internal data model.  There are also technical reasons, for example, you don’t want to litter your internal data model with WCF attributes.  So you end up having a bunch of classes that represent your service contract that are similar to but not the same as your internal data model.  Therefore, there is overhead maintaining the mappings between those two object models – this is where AutoMapper helps.  AutoMapper also helped reduce the amount of code we had to write to start off with, but that is a one off cost and doesn’t really take that long to write (even though after 30 mins of a.x = b.y does make you want to pull out your eyes).  The biggest win is maintenance by far.

If you’re in control of your contract / object model it is a good idea to make life as easy for yourself as possible.  For example, try and make property names match – hopefully they naturally will. That way AutoMapper will map, by convention, most of your properties automatically.  80% of what you need for 20% of the effort!

You can download AutoMapper via Horn, which I find the easiest way to get the latest version of open source binaries!

To help illustrate what I’m talking about I’ll finish with an example.  I haven’t shown the projects usage (it wouldn’t make sense unless you’d like to first understand trade settlement data) but here’s an example (contrived a bit):

   1: // setup the mapper
   2: Mapper.CreateMap<ServiceContract.Customer, Domain.Customer>()
   3:    .ForMember(c => c.Products, opt => opt.MapFrom(sc => sc.InterestedIn));
   4: Mapper.CreateMap<ServiceContract.Product, Domain.Product>()
   5:    .AfterMap((contractProduct, domainProduct)
   6:              => domainProduct.ProductType = LookupProductType(contractProduct.Name));
   7: Mapper.CreateMap<ServiceContract.Address, Domain.Address>();
   8:  
   9: // setup some data
  10: var serviceCustomer = new ServiceContract.Customer
  11:                          {
  12:                             Firstname = "John",
  13:                             Surname = "Smith",
  14:                             DateOfBirth = new DateTime(1980, 10, 10),
  15:                             Address = new ServiceContract.Address {HouseName = "1", Postcode = "postcode"}
  16:                          };
  17: serviceCustomer.InterestedIn.Add(new ServiceContract.Product{Name = "Something for the wife"});
  18:  
  19: // map it
  20: var domainCustomer = new Domain.Customer();
  21: Mapper.Map(serviceCustomer, domainCustomer);
  22:  
  23: private static ProductType LookupProductType(string name)
  24: {
  25:    // do some db lookup maybe
  26: }

As you can see AutoMapper can also update an instance object, so if someone wanted to provide updates to existing objects then it’s a piece of cake too!

Here are the classes which are being mapped:

   1: namespace Domain
   2: {
   3:  
   4:    public class Customer
   5:    {
   6:       public Customer()
   7:       {
   8:          Products = new ProductCollection();
   9:          ContactHistory = new ContactHistory();
  10:       }
  11:  
  12:       public string Firstname { get; set; }
  13:       public string Surname { get; set; }
  14:       public DateTime DateOfBirth { get; set; }
  15:       public Address Address { get; set; }
  16:       public string EmailAddress { get; set;}
  17:  
  18:       public ProductCollection Products { get; private set; }
  19:  
  20:       // extra stuff on customer that you don't want third parties to provide
  21:       public ContactHistory ContactHistory { get; private set; }
  22:       // .....
  23:    }
  24:    
  25:    public class ContactHistory
  26:    {
  27:    }
  28:  
  29:    public class Address
  30:    {
  31:       public string HouseName {get; set;}
  32:       public string Postcode { get; set; }
  33:    }
  34:  
  35:    
  36:    public class ProductCollection : List<Product>
  37:    { }
  38:  
  39:    public class Product
  40:    {
  41:       public ProductType ProductType { get; set; }
  42:    }
  43:  
  44:    public class ProductType
  45:    {
  46:       public string Name { get; set; }
  47:    }
  48: }
  49:  
  50: namespace ServiceContract
  51: {
  52:    [DataContract]
  53:    public class Customer
  54:    {
  55:       public Customer()
  56:       {
  57:          InterestedIn = new List<Product>();
  58:       }
  59:  
  60:       [DataMember]
  61:       public string Firstname { get; set; }
  62:       [DataMember]
  63:       public string Surname { get; set; }
  64:       [DataMember]
  65:       public DateTime DateOfBirth { get; set; }
  66:       [DataMember]
  67:       public Address Address { get; set; }
  68:       [DataMember]
  69:       public string EmailAddress { get; set; }
  70:       [DataMember]
  71:       public List<Product> InterestedIn { get; set; }
  72:    }
  73:  
  74:    [DataContract]
  75:    public class Product
  76:    {
  77:       [DataMember]
  78:       public string Name { get; set; }
  79:    }
  80:  
  81:    [DataContract]
  82:    public class Address
  83:    {
  84:       [DataMember]
  85:       public string HouseName { get; set; }
  86:       [DataMember]
  87:       public string Postcode { get; set; }
  88:    }
  89: }

Some more examples can be found on the codeplex site:  http://www.codeplex.com/AutoMapper

Humax freesat receiver not recording two channels concurrently

 

I was having some trouble getting my Humax Freesat receiver (the FOXSAT-HD model) recording two channels at the same time.  The reason I was having trouble is due to the fact that when I initially used the device I had only connected it with a single digital input.  I later connected both inputs (when I had extra cabling installed).  The Humax box detected that both tuners were connected but I could not view all channels when I was recording.

To fix it I had to do a factory reset.  Fortunately, when you do this it doesn’t wipe all your recorded stuff (think it wiped my record schedule though but not sure if it’s my bad memory).  When the box restarts it takes you through the initial set up and should detect both satellite inputs and tunes them in.  I can now record and watch TV at the same time.

I’d still highly recommend the Humax Freesat receiver to anyone looking for such a device.  I had the Freeview receiver before I upgraded to Freesat and that was pretty good too!

Hope this helps someone else!

Defer decisions and remove dependencies – Lean ways to quick delivery

 

In the previous post I discussed waste and how to reduce with TDD and refactoring. In this post I’m going to focus on how you defer decisions and remove dependencies.

Wrong decisions that have to be undone or worked around are a massive cause of waste. Making the right decision can only happen when you have enough information available – thus you make an informed choice. The old fashioned (well not that old!) way of solving this problem is write a spec, speak to people and validate your approach with them – essentially gathering information which will help you make the right informed choice. There’s another way, experimentation – come up with a hypothesis of how you think something should work and test it (experiment) – validate your hypothesis. This is essentially “working software over comprehensive documentation” from the agile manifesto. What often stops this frequent demonstration of software is dependency on things that are needed but aren’t yet ready. Commonly you’ll have concurrent teams working on features that are required for each other to work. Sometimes hundreds of lines of code are written before you validate the need with a demo (or better through use) – thus those hundreds of lines of code could be wasted. However, these dependencies are artificial – they don’t need to be there.

So, how do you defer decisions and remove dependencies? Interestingly, the two can be achieved at the same time. You may want to demonstrate some functionality to a user but the underlying capabilities are not yet delivered (and will not be for a considerable amount of time). But you do have a high level understanding of what that capability will look like – its interface. That understanding will evolve as you build the solution, so making it easy to grow and change is crucial (refactoring should be easy). A premise behind service–orientation is that what an organisation does remains pretty stable, what changes is how they do it. Knowing what something needs to do and defining the input and output. You can then create a mock of the implementation (i.e. mock out the how). Thus, you’ve removed the dependency and deferred the decision about how to do it until you need to solve it. This links in with the I ‘interface separation’ and D ‘dependency inversion’ from SOLID. From a high level architectural view it is the beginnings of the development of service interfaces and message exchange patterns... The plus to this is separate people can work without dependency on each other but together on the development of an entire system. Inverting your dependency on something also means that if you do make a wrong choice, or something better comes along, it can be easily changed.

There are times where you can’t defer a decision until later.  For example, having a consistent architecture is important, Brooks talks about it in terms of conceptual integrity and the advantages it gives in terms of maintainability. There are some decisions about the approach you’re going to take that you must make early on in the process... You can do your best to make sure you’ve got dependency inversion between your components and layers so that if you make a wrong decision you can swap it out. But changing your mind on large, often crucial parts of the system, costs time and money... So even if you could swap out something you might not want too. The key thing to remember is make a decision when you have enough information to make it. So, in this case, candidate architectures or proof of concepts are a great way to help create that information. They are great at breaking assumptions – and have proved invaluable when building solutions in new technologies or new business domains. Those candidate architectures can be thrown away, but they aren’t waste because they generated information valuable in making the right choice, which if made wrong would create a huge amount of waste.

Add Comment Filed Under [ Lean ]
Reducing Waste – Lean ways to write code

 

In my previous post I introduced a few lean concepts and set out to tell a tale how those concepts can be applied to the day to day task of cutting code... I picked 3 areas, reducing waste, removing artificial dependencies and building quality into the process.

Let’s start with waste. Waste in the software process has many disguises... In lean manufacturing a large stock inventory is waste. Tom and Mary highlighted that unused features are essentially an inventory; an unused feature is a waste. Another, and probably a much more obvious waste to non-lean thinkers is a bug. Think about this, bugs in unused features are utter waste!

What are unused features though? The clear unused feature to a user is a screen they never use. But to a developer, it’s over engineered code, generic frameworks that have a single application, developing something that already exists (the not made here syndrome)... Agile methods work hard to reduce the statistics of unused features by not having big up front specs, by constant demonstration of software and by re-prioritisation of work backlogs. But developers must also work hard not to create code waste. YAGNI – you aren’t going to need it. It’s a simple statistic, the more code the more bugs. No code, no bugs. We can’t yet write no code to implement solutions (unless you’re a SharePoint guru :) ) so we must aim to write as little as possible. I said before I wouldn’t focus on process, but it is absolutely crucial that you develop the least amount of features for a system that will leave your customer delighted. With that digression out of the way I’ll assume you’re now working on a feature that will be used 90% of the time – how do you make sure you don’t introduce waste in code?

Well here’s a paradox – the answer is to write more code, specifically – write test code. Why isn’t test code waste, the user doesn’t use it the business doesn’t get value from it – its waste? That argument is valid sometimes, sometimes there just isn’t time, sometimes you literally do have a day or two to get something out the door, then test code would be waste. One thing to remember in everything you do is that being pragmatic is the most important thing... The pragmatic guy needing to meet a new regulatory requirement (ignored by the business for months) will get something out the door. The same pragmatic guy also will write tests, he’ll make sure when he’s not commercially constrained, he builds time into his project to build tests.

I can remember having a discussion once with a finance director about project timescales, and being open and honest with him I explained the need to do certain things. He doesn’t care about the software development process or the tasks I have to do to give him software that’s going to make him hundreds of thousands of pounds a month. All he cares about is the fact that if he had it now, he’d be making that money and every day he doesn’t have it he’s losing that money. But, he also understood that me not doing a job properly could result in his call centre not being able to operate and not making any money – so reluctantly, he let me do it properly (pragmatically) (he still squeezed me, but we dropped features not quality).

I think it’s clear enough that if you write tests it will take longer to deliver the solution (there’s simply more to do). In fact, Microsoft have done some empirical research and found it does take longer (have a read here http://research.microsoft.com/en-us/news/features/nagappan-100609.aspx). But they also found that teams using TDD (Test Driven Development) had a lot fewer live defects. TDD measurably increased in process quality. Again, there are two sides to the argument – if a commercial pressure dictates that you simply must get something done you may be willing to have a few live defects (I’ll talk more about quality in a later post...).

A commonly used approach with TDD is “red green refactor”. Write a test, run it; it will fail (red). Make the test pass (green). Then refactor. The idea behind it is you write the least amount of code possible to get the test passing, thus ingrained into the approach is the concept of writing less code.

The refactor step is crucial. Without it, you would repeat yourself... Repeating yourself results in more code (thus more bugs). So, refactoring is also a critical part in writing less code. The key idea with the refactor approach is that you only introduce something when you know you need it. You don’t start off from a point thinking you’re going to need it and write more code than you actually need. The likelihood is you won’t need it, so it’s waste.

TDD should also mean you write fewer tests too. Bashing out a load of code (with loads of things you’ve added in that you don’t need) means that when you retrospectively add tests you need to test more stuff, thus write more tests.

TDD also meets another core lean principle; defer the decision about something until have the information. You only write production code when you know you need it; you only refactor code to use a design pattern when you know you need it... You don’t start off thinking you need it, you wait until you know...

Another aspect of writing less code is using more code that has already been written and tested. The downside of using solutions that already exist is that they will probably do 80% of what you need and have features which you only use 10% of. Now, this is a problem if you have to pay for the software – sinking a lot of money into a something you only use 10% of is wasteful. If that 10% is very hard to do yourself then you’ll probably still spend the money (the best example of this is a database, pretty much all projects need a database, you’d never write your own but you probably only use a small proportion of its features from one project to another...). This is what’s great about Open Source Software (OSS). It’s free. So, there is no money spent thus no incurred waste. There may still be code in that OOS solution that you don’t use, but you didn’t write it, hopefully someone else is using it, so it’s not waste. If you need something, you can contribute to the OSS project and add it in. Or if it’s very specific, you can extend it yourself. Extending existing solutions is also possible with existing paid for solutions, as long as those solutions are extensible. Extending something is again less code from building it all from scratch. Picking extensible components to build a solution on top of is a great way to reduce the amount of code you have to write and test.

I’ve focused on tests teasing out production code, I’ve not touched on the impact tests have on quality – for that, read the last post in this series...

Add Comment Filed Under [ Lean ]
Introduction – Why lean makes sense in software development

kanban

Having spent the day with the Poppendiecks last month I came out enthused again about software development. When working at the coal face it’s great to have an opportunity to sit back and look at the bigger picture. Tom and Mary are fantastically passionate speakers that meeting them is a really great opportunity and I highly recommend if they are speaking anywhere near you, you make a point of going to listen. If not, you can read their books, which are full of interesting and pertinent real world anecdotes (just like their talks).

Picture to the right is Mike on a night out, sporting his own Kanban board…

I’m going to try not to regurgitate their content but rather add some thoughts about how a lean approach is applicable, every day, to software development... I’m going to focus on how the underpinning concepts of lean actually correlate quite tightly with good software design and architecture. I don’t think it’s anything new, but I think it’s interesting anyway...

As a developer while listening to Tom and Mary the three things that struck home were... Firstly, that the most important concepts of lean is kaizen, or improvement. The reason for improvement is to eliminate waste. Specifically waste is things that don’t add any value. Secondly, in lean continuous improvement is supported by a fundamental belief that quality should be built into the process. To address ‘in process quality’ lean manufacturing advocates a stop the line mentality – when a problem occurs, stop and fix it. Thirdly, another important concept is the need to remove artificial dependencies (as process dependencies can create waste). Lean recognises that another reason for waste is making the wrong decisions; so lean advocates deferring a decision until you have as much information as possible (thus reducing the likelihood of making a wrong decision).

I did say I wouldn’t regurgitate material, but this sets up some context for what I’m going to talk about – it’s very high level so to find out more have a read of Lean Software Development. Also, there is much more to lean, I’ve just picked out some key ideas...

There are glaringly good reasons why lean concepts align so well with development process – and if you don’t specifically do lean you’re probably doing a lot of what being lean requires. For example, test driven development, continuous integration, frequent drops of demonstrable software etc. Just a question though, how many of you, when the build breaks, drop tools and fix the build before going on?

What I am going to focus in on is the importance good coding practices can have on being lean. There are quite a lot of opposing views on this out there, about whether SOLID is good or not, whether you should do TDD etc. I don’t want to get drawn into that argument here, rather just show how some concepts really line up with being lean.

This started out as one big post but I’ve split it up into smaller posts, the next post will look at ways of reducing waste, followed by reducing dependency hierarchies and finally bringing it all together with building quality into the process.

Add Comment Filed Under [ Lean ]
Batching SQL statements with Oracle (ODP.Net)

 

Continuing the theme of my last post, more on Oracle.  I have enjoyed porting a legacy application to Oracle (ok – maybe a bit sarcastic!).  I wish nHibernate existed when this product was first written, it would have been a much easier job.  Actually, in all fairness it’s been pretty painless – the application has it’s own data layer / ORM (object relational mapper) which abstracts away all the SQL so the main application hasn’t had to change that much.  Thank god for separation of concerns otherwise this port would have taken 10 maybe 100 times longer!  Refactoring the application to use nHibernate would have been an even bigger challenge, the app’s been around a bit and there’s no real dependency inversion on the ORM layer (if there was then it would have been a easy job to swap out the ORM to nHibernate!).  True dependency inversion between layers might feel like a waste of time but when you come back to a product 2 years later and need to adapt it for a new customer it can help – maybe I’ll do a post on that later…

Got a bit sidetracked there, the problem we had to solve was to batch SQL statements up into a single command so we can execute it in one go (this is how the SQL Server implementation works).  This is nothing ground breaking and the performance gains are pretty obvious, lots of chatty network calls when calling ExecuteNonQuery() will no doubt increase the time it takes to persist an object graph.  But creating a command containing lots of inserts / updates / deletes / stored proc calls using the OracleCommand (in ODP.Net) isn’t obvious, so I thought I’d share the findings.  The solution is actually pretty simple.

First attempt was the most obvious, cmd.CommandText = “insert into table (values :p1, :p2); insert into table (values :p3, :p4);”.  No joy, get invalid character (didn’t like the semi colon).  At this point I was a bit worried it might not be possible, but I thought it must be possible otherwise some people would have some serious scalability issues (the application we’re working on has some seriously high scalability requirements)!  So, I started playing in the debugger and guessed at cmd.CommandText = “begin insert into table (values :p1, :p2); insert into table (values :p3, :p4); end;” – that worked!  Once I’d figured that out it didn’t take me long to see on Google that using begin … end was the way to go… I also found this article on on optimising performance with ODP.Net

Few things to watch out for… If you have any carriage returns in your command text you get an error, so when building up your SQL make sure you don’t add any…  You can call stored procedures, out parameters work and so do sys_refcursors.  Only down side is when calling a proc you must specify the parameters in the correct order, you can’t use parameter name binding as you would when using the StoredProcedure CommandType.

You can batch up select statements too: "begin open :p for select * from BulkTesting; open :p1 for select * from BulkTesting; end;" You’ll need to make sure you set your command up with out parameters for each of your cursors, i.e. cmd.Parameters.Add(":p", OracleDbType.RefCursor, ParameterDirection.Output);".  Then you can either use the OracleDataAdapter to fill a data set or ExecuteReader (use NextResult() to move to the next cursor of data).

Now to check it gives me a performance boost (bit of really simple test code here):

   1: using (var connection = new OracleConnection(connectionString))
   2: {
   3:    connection.Open();
   4:  
   5:    var sw = Stopwatch.StartNew();
   6:    using (var cmd = connection.CreateCommand())
   7:    {
   8:       var cmdText = new StringBuilder();
   9:       cmd.BindByName = true;
  10:       cmd.CommandType = CommandType.Text;
  11:  
  12:       cmdText.Append("begin ");
  13:       for (var i = 0; i < 500; i++)
  14:       {
  15:          cmdText.AppendFormat("insert into BulkTesting values (:id{0}, :data{0}); ", i);
  16:          cmd.Parameters.Add(string.Format(":id{0}", i), i);
  17:          cmd.Parameters.Add(string.Format(":data{0}", i), string.Format("bit of data for {0} call", i));
  18:       }
  19:       cmdText.Append(" end;");
  20:  
  21:       cmd.CommandText = cmdText.ToString();
  22:       cmd.ExecuteNonQuery();
  23:    }
  24:    sw.Stop();
  25:    Console.WriteLine("Batch query took {0}", sw.ElapsedMilliseconds);
  26:  
  27:    sw = Stopwatch.StartNew();
  28:    for (var i = 0; i < 500; i++)
  29:    {
  30:       using (var cmd = connection.CreateCommand())
  31:       {
  32:          var cmdText = new StringBuilder();
  33:          cmd.BindByName = true;
  34:          cmd.CommandType = CommandType.Text;
  35:  
  36:          cmdText.AppendFormat("insert into BulkTesting values (:id{0}, :data{0}) ", i);
  37:          cmd.Parameters.Add(string.Format(":id{0}", i), i);
  38:          cmd.Parameters.Add(string.Format(":data{0}", i), string.Format("bit of data for {0} call", i));
  39:  
  40:          cmd.CommandText = cmdText.ToString();
  41:          cmd.ExecuteNonQuery();
  42:       }
  43:    }
  44:    sw.Stop();
  45:    Console.WriteLine("Multiple queries took {0}", sw.ElapsedMilliseconds);
  46: }

Gave these results:

oracle statement batching

So In summary, it’s not hard once you’ve got begin end; involved :).  If any gurus reading know of an alternative, please let me know!

Add Comment Filed Under [ Oracle ]
OracleGlobalization - making queries case insensitive in oracle

 

We needed a solution that made text matching in SQL queries case insensitive.  Some Googling we found we could do this:

   1: alter session set nls_comp=ansi;
   2: alter session set nls_sort=binary_ci;
   3:  
   4: select * from casetest where "field" = 'tom'

If you look at the execution plan (shown below), you’ll see the SQL that actually gets run.

execution plan for case insensitive search

It’s important to note that because if you want to use an index (as you see above) you’ll need to add a function index (shown below).  A standard index on the field column won’t get used.

   1: create index ix_casetestfunc on casetest (NLSSORT("field", 'NLS_SORT=BINARY_CI'))

So, how do you set that up in code (.Net)?  You can use the OracleGlobalization class (see here for more info)…  This class lets you alter the session without needing to run the alter session sql…

Now, this is great but I had a few problems…  Firstly, I kept getting an error when I tried to set my changes to OracleGlobalization (by calling SetThreadInfo – was getting the same error with connection.SetSessionInfo).  The error I got was "ORA-12705: Cannot access NLS data files or invalid environment specified".  I was getting this error when I ran the following OracleGlobalization.SetThreadInfo(OracleGlobalization.GetThreadInfo()); – which shouldn’t happen because all the data should be valid, I was just given it!  A jump into reflector to have a look what was going on didn’t help as it pretty much delegates off to a Win32 call straight away…  So I had a look at all the parameters on the instance of OracleGlobalization and cross referenced them with values in the database to find that the value for ISOCurrency is wrong it was “UNITED “.  So I made an educated guess and set it to UNITED KINGDOM in the debugger and it worked!

Next problem I found was that the code below made no difference to my queries…  I guessed based on the API that by calling SetThreadInfo all my connections created on that thread would get my modified OracleGlobalization instance… No, I was wrong – in fact – nothing gets it.  If you call GetThreadInfo immediately after calling SetThreadInfo you get the original instance…

   1: var data = OracleGlobalization.GetThreadInfo();
   2: data.ISOCurrency = "UNITED KINGDOM";
   3: data.Sort = "BINARY_CI";
   4: data.Comparison = "ANSI";
   5: OracleGlobalization.SetThreadInfo(data);

The code below works, which caused significant elation I might add!

   1: using (var con = new OracleConnection("..."))
   2: {
   3:    con.Open();
   4:    var data = con.GetSessionInfo();
   5:    data.ISOCurrency = "UNITED KINGDOM";
   6:    data.Sort = "BINARY_CI";
   7:    data.Comparison = "ANSI";
   8:    con.SetSessionInfo(data);
   9:    using (var cmd = con.CreateCommand())
  10:    {
  11:       cmd.CommandText = "select * from casetest where \"field\" = 'tom'";
  12:  
  13:       using (var reader = cmd.ExecuteReader())
  14:       {
  15:          while (reader.Read())
  16:          {
  17:             Console.WriteLine(reader[0]);
  18:          }
  19:       }
  20:    }
  21: }

I hope this story saves someone else spending a lot of money in a swear box.  Not sure if the issues I had are environmental (I’m running Oracle Database 10g Express Edition Release 10.2.0.1. on a Windows 7 box – although I tested it on a Vista box too with the same problems).  As always, if anyone knows a better way of solving this problem please let me know.

2 Comments Filed Under [ Oracle ]
WindsorContainer specifying Lifestyle programmatically

On a project I've been using Castle's IOC Container.  On the other recent projects I've been using Unity for IOC.  One difference between Unity and Windsor is the default lifestyle (or in Unity LifetimeManager).  On the UnityContainer if you do not specify a LifetimeManager then the lifetime is transient (this means that for each call to Resolve a new instance of your type will be returned).  When using the Windsor container the default lifestyle is Singleton (which means that for each call to Resolve the same instance of the type is returned).  I guess it's a matter of preference what you want to happen here.  My opinion is that if it's a singleton and you don't know it's a singleton you could get some very hard to track down bugs (concurrency issues, state management problems etc).  If you know it's a singleton and you want it to be a singleton then that's fine.  Therefore, I prefer to make everything transient by default and you have to ask for it to be a singleton (not sure what others think but that's my thought).  Another reason is that I want other people more used to the Unity container to get transient by default (I'm not sure what Structure Map and the others do?).

So there are two requirements here, the first is by default use a transient lifestyle and the second is to be able to specify the lifestyle when registering a type (adding a component to use Windsor's term).

You can do this in two ways out of the box, in the XML configuration or by attributing your classes (see here for more info).  I'm not doing either, I'm configuring my container in code (I prefer configuring my container in code because it's refactor friendly - i.e. when I rename my interface or class I don't have to remember to go and update my XML configuration, also, it's quicker to type!).

In the Unity world when you register a component you can specify the lifetime manager you want to use - there isn't a way (I can see) to do the same with Castle.  But castle is extensible so I extended it to meet my need.

In my project I've hidden the IOC container behind my own interface, this helped me no end when I came to do this as my Container Configuration class just had an IIocContainer to work with):

public class ContainerConfiguration
{
  private readonly IIocContainer container;
 
  public ContainerConfiguration(IIocContainer container)
  {
     this.container = container;
  }
 
  public void Configure()
  {
     container.Register<IAuthenticationService, FormsAuthenticationService>();
     ....
  }

My implementation for the Castle container now uses my implementation of IContributeComponentModelConstruction to specify the lifestyle when I register the type (by default it registers it with a Transient lifestyle and there's an override that let's you specify the one you want):

public class MyProjectsContainer : IIocContainer
{
   private readonly IWindsorContainer container;
   private readonly LifestyleResolver lifestyleResolver = new LifestyleResolver();
 
   public PBRCastleWindsorContainer(IWindsorContainer container)
   {
      if (container == null) throw new ArgumentNullException("container");
      this.container = container;
      this.container.Kernel.ComponentModelBuilder.AddContributor(lifestyleResolver);
   }
 
   public void Register<T, U>()
      where U : class
   {
      lifestyleResolver.SetLifestyle(typeof(U), LifestyleType.Transient);
      container.AddComponent<T, U>();
   }
.....

For completes the IContributeComponentModelConstruction implementation:

public class LifestyleResolver : IContributeComponentModelConstruction
{
  private readonly Dictionary<Type, LifestyleType> configuration = new Dictionary<Type, LifestyleType>();
 
  public void ProcessModel(IKernel kernel, ComponentModel model)
  {
     LifestyleType lifestyleType;
     if (configuration.TryGetValue(model.Implementation, out lifestyleType))
     {
        model.LifestyleType = lifestyleType;
     }
  }
 
  public void SetLifestyle(Type type, LifestyleType lifestyleType)
  {
     configuration.Add(type, lifestyleType);
  }
}

Again, hope this helps and if anyone knows a better way let me know!

Fluent NHibernate Auto Persistence Model and composite element lists

If you're using Fluent NHibernate AutoPersistenceModel and have struggled when you want to define a one to many relationship as a composite-element then this blog may help you.

When using the AutoPersistenceModel the mapping generated for a relationship by default looks like the following:

   1: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="">
   2:   <class name="Parent" xmlns="urn:nhibernate-mapping-2.2">
   3:     <id name="Id" type="Int32" column="Id">
   4:       <generator class="identity" />
   5:     </id>
   6:     <property name="Property" type="String">
   7:       <column name="Property" />
   8:     </property>
   9:     <set name="Children">
  10:       <key column="ParentID" />
  11:       <one-to-many class="child" />
  12:     </set>
  13:   </class>
  14: </hibernate-mapping>

For clarity the class would look something like

   1: public class Parent
   2: {
   3:     public string Property {get; set;}
   4:     public ISet<Child> Children {get; set;}
   5: }
   6:  
   7: public class Child
   8: {
   9:     public string ChildProperty {get; set;}
  10: }

Now - what if you want the Child to be a composite element?  When hand writing the mapping you'd just change it to something like below:

   1: <set name="Children" cascade="all-delete-orphan" lazy="false">
   2:   <key column="ParentID" />
   3:   <composite-element class="Child">
   4:     <property name="ChildProperty">
   5:       <column name="ChildProperty" />
   6:     </property>
   7:   </composite-element>
   8: </set>

If it wasn't a list you could use WithSetup as shown below.

   1: AutoPersistenceModel.MapEntitiesFromAssemblyOf<Parent>()
   2:    .WithSetup(e => e.IsComponentType = t => t == typeof (Child));

However, the code above doesn't work for a list.

You can use the fluent API to make a composite list which the code below demonstrates:

   1: mapping.ForTypesThatDeriveFrom<Parent>(m => m.HasMany(p => p.Children).Component(comp =>
   2:  {
   3:     comp.Map(child => child.ChildProperty);
   4:  }));

My bug with this is it's already generated the mapping for Child, why do I need to specify it again when saying it's a component.  It would be nice if the WithSetup let me do it but it doesn't so I've had to write my own code to do the same thing...

I'm working on a small project with a very simple model and AutoPersistenceModel does 90% of what I need - the last 10% is that I want some of my types to be composites (at the moment anyway)...  I want to try and keep it nice and clean, i.e. don't mix manual configuration with auto configuration.  I much prefer the NHibernate XML configuration to using the Fluent API as I think it's easier to read (albeit a bit less refactor friendly).  So, I was at the point of throwing away AutoPersistenceModel and hand cranking out my XML.  But I thought I'd try and make something that could do what I wanted.  My scenario isn't that complicated, I have no idea if this code will work well for more complicated models with composite of composites but it's a start (my model may evolve to something like this so never know I may need to solve it, or use mapping xml).

So with my new extension method I can now do this:

   1: var referenceMapping = AutoPersistenceModel.MapEntitiesFromAssemblyOf<Parent>();
   2: var mapping = AutoPersistenceModel.MapEntitiesFromAssemblyOf<Parent>()
   3:    .ReconfigureToComposite<Parent, Child>(referenceMapping, "Children");

I don't have to redefine the mapping for Child.

The extension method looks like this:

public static class FluentNHibernateExtensionMethods
   {
      public static AutoPersistenceModel ReconfigureToComposite<TRoot, TChild>(this AutoPersistenceModel mapping, AutoPersistenceModel referenceMapping, string propertyName)
      {
         var mappings = new List<Expression<Func<TChild, object>>>();
 
         var childMapping = referenceMapping.FindMapping(typeof(TChild));
         foreach (var property in childMapping.GetClassMapping().Properties)
         {
            var param = Expression.Parameter(typeof(TChild), "p");
            var prop = Expression.Property(param, property.PropertyInfo);
            mappings.Add(Expression.Lambda<Func<TChild, object>>(prop, param));
         }
 
         var hasManyParam = Expression.Parameter(typeof (TRoot), "r");
         var hasManyExpression = Expression.Lambda<Func<TRoot, object>>(Expression.Property(hasManyParam, propertyName), hasManyParam);
 
         mapping.ForTypesThatDeriveFrom<TRoot>(
            m => m.HasMany<TChild>(hasManyExpression).Component(c =>
               {
                  foreach (var map in mappings)
                  {
                     c.Map(map);
                  }
               })
               .Cascade.AllDeleteOrphan()
               .Not.LazyLoad());
 
            return mapping;
      }
   }

Hopefully someone will find this useful.  If anyone knows an easier way to achieve the same thing then please let me know (maybe I missed something or maybe they'll release a new feature soon :)).

Add Comment Filed Under [ NHibernate ]
DataGridView paging using virtual mode

You can download the code for this blog post from here

Paging is a great way to limit the amount of data displayed to the user at one time, but is also a very good way of stopping lots of data being transmitted across the network, being held in memory or big queries on databases...  It solves many problems. 

The most common solution is (just like on a Google search) is you get shown a list of pages and you can navigate around pages either going up / down a page at a time or clicking on a page number. 

Another way is to make it seem like there is actually one big list but page behind the scenes so the user feels like they are actually viewing one big list.  An example where you see this done is in TFS.  You can do this with a windows forms data grid (DataGridView).

DataGridView has two main modes.  The first is the most common, you data bind your grid to a data source and all the data in that source is loaded into the grid.  This is very easy to do, but with big lists of data can get quite slow!  The other is virtual mode, where you are notified when data is required for a row and you populate it.  That works much better for big lists as the grid only loads what is currently on the screen and when the cells are no longer visible they are destroyed...

The paging solution uses the grid in virtual mode:

   1: gridPager = new PagedVirtualDataGridController<TestData>(
   2: new PagedVirtualDataGridView<TestData>(dataGridView1, gridColumnMapper), 100, (pageNumber, pageSize) =>
   3:  {
   4:     // delegate to fetch the page...
   5:  });

Bit of background reading on the DataGridView and the VirtualMode property can be found in this walk through.

When working in virtual mode it becomes easier to page as the grid will only request what it needs.  However, it does mean you lose data binding.  Setting up the columns is easy, just add them through the designer.  But, when the CellValueNeeded event is raised we need to know what information is required for that cell.  This is where the GridColumnMapper comes in, it enables you to specify what value should be returned for each column (in the sample above you can see that gridColumnMapper is being passed into PagedVirtualDataGridView):

   1: gridColumnMapper = new GridColumnMapper<TestData>();
   2: gridColumnMapper.AddMapping(0, t => t.Name);
   3: gridColumnMapper.AddMapping(1, t => t.Value);

The paged grid is implemented using the MVC (Model View Controller) pattern.  The view (IPagedVirtualGridView) is an abstraction of the DataGridView - it exposes only what is needed to enable paging.  The PagedVirtualDataGridView (which implements IPagedVirtualGridView) accepts a DataGridView and GridColumnMapper in its constructor.  The view listens to its Model (an IPagedDataModel) and handles the PageFetchCompleted event.  When this event is fired it causes the DataGridView to request data for the cells which are contained on the page which was just fetched (using UpdateCellValue).

The Model (PagedDataModel : I PagedDataModel) contains all the pages which have been fetched and is responsible for asynchronously fetching the page.  It uses a FetchPageDelegate to actually go and fetch the page.  If the page has already been fetched then that data is returned synchronously (all fetched pages are stored in a dictionary).  If the page has not been fetched then it queue a thread pool work item to fetch the page.  There is some synchronisation code to ensure only one page is fetched at a time and the same page is not fetched more than once.  When the page is fetched it raises the PageFetchCompleted thus notifying the view to refresh its cells.

The controller is attaches to the IPagedVirtualGridView CellValueNeeded event and asks the model for the object which relates to that cell.  If there is data available then it sets the DataGridViewCellValueEventArgs Value property using the views column mapper.

At the moment this implementation is read only, but it wouldn't be difficult to use the CellValuePushed event to ensure data is written back to the Model.

I've uploaded a solution where you can download the code plus a simple example.  The usage on the sample form is below.  The example delegate sleeps (simulating it going back to the server to get some data).

   1: gridColumnMapper = new GridColumnMapper<TestData>();
   2: gridColumnMapper.AddMapping(0, t => t.Name);
   3: gridColumnMapper.AddMapping(1, t => t.Value);
   4:  
   5: var data = new List<TestData>();
   6:  
   7: for (var i = 0; i < 100000; i++)
   8: {
   9:    data.Add(new TestData { Name = string.Format("Number {0}", i), Value = i.ToString() });
  10: }
  11:  
  12: dataGridView1.RowCount = data.Count;
  13:  
  14: gridPager = new PagedVirtualDataGridController<TestData>(
  15:    new PagedVirtualDataGridView<TestData>(dataGridView1, gridColumnMapper), 100, (n, s) =>
  16:     {
  17:        Thread.Sleep(500);
  18:        if (n * s > data.Count)
  19:           return null;
  20:        var items = new TestData[s];
  21:        for (int y = n * s, p = 0; y < (n + 1) * s && y < data.Count; y++, p++)
  22:        {
  23:           items[p] = data[y];
  24:        }
  25:        return items;
  26:     });
One Comment Filed Under [ Windows Forms ]