Friday, November 11, 2011

The difference between bad code and good code

A colleague asked for some advice today on a project that he inherited (which I am extending with a separate module incidentally).

The issue was related to the usage of Entity Framework in the code that he had to maintain, and he needed some advice on how to proceed.  The problem was that the service layer was calling the repository multiple times, but each repository method was wrapped in a separate unit of work.
e.g.

public void DeleteEntity(int entityID)
{
    using (var context = EntityContext())
    {
        var entity = context.Postings.SingleOrDefault(p => p.entityID == entityID);
        context.Entities.DeleteObject(entity);
        context.SaveChanges();
    }
}
and
public Entity GetPosting(int entityID)

{
    using (var context = EntityContext())
    {
        return context.Entities.FirstOrDefault(p => p.entityID == entityID);
    }
}
This caused two problems for the developer, who needed to perform a complex action in his service that referenced multiple repository calls.
  1. He had no control over the transactional scope for the repository methods
  2. Each operation was on a separate EF context, so the service could not load and entity, edit it, and then save the changes (unless the repository was designed for disconnected entities, which it wasn't).
From a maintainability and testability point of view this was also a very poor design, as the repository methods created instances of dependency object (the service method also created instances of the repositories, making the services inherently untestable).


The version of this design that I implemented for my component follows a similar service/repository/entity pattern, but is implemented in a far more testable and robust manner.

The first improvement over the legacy design is in the dependency management
My service accepts a context and all required repositories in the constructor, and my repositories accepts a context, which allows for improved maintainability (all dependencies are described) and testability (all dependencies can be mocked).  This also allows us to use dependency injection/IoC to create our object instances.

The second improvement was in the Unit of Work design.
Rather than have each repository method as a single unit of work, the service methods are the units of work, so any action within the service uses the same context (as it is passed as a dependency to the repositories that the service uses), and each service call acts as a Unit of Work, calling SaveChanges at the end of the service to ensure that the changes act under a single transaction.
There are limitations to this design (your public service methods become an atomic transaction and you should not call other public methods from within another method) but for simplicity and maintainability it is a pretty good solution.

Below is a simple example of the design I am using, preserving maintainability, testability, and predictability.  I'm not saying it is necessarily the best code around, but it solves a number of issues that I often see in other developers code.

public class HydrantService
{
  public HydrantService(HydrantsSqlServer context, EFRepository<Hydrant> hydrantRepository, EFRepository<WorkOrder> workOrderRepository, EFRepository<HydrantStatus> hydrantStatusRepository)
  {
    _context = context;
    _hydrantRepository = hydrantRepository;
    _workOrderRepository = workOrderRepository;
    _hydrantStatusRepository = hydrantStatusRepository;
  }
  public void createFaultRecord(WorkOrder order)
  {
    HydrantStatus status = _hydrantStatusRepository.GetSingle<HydrantStatus>(x => x.StatusCode == "Fault"); //_context.HydrantStatuses.Where(x => x.StatusCode == "Fault").FirstOrDefault();
    order.Hydrant.HydrantStatus = status;
    _workOrderRepository.Add(order);
    _context.SaveChanges();
  }
}

  public class EFRepository<T>
 {
 public EFRepository(IDbContext context)
 {
    _context = context;
  }   public virtual ICollection GetAll()

  {
    IQueryable query = _context.Set();
    return query.ToList();
  }
}

Thursday, November 10, 2011

Social Communities

This is a bit of an introspective post about my own interaction with social, online and gaming communities.
I have always been fairly anti-social, and aside from a small group of close-knit friends I have never felt comfortable in social situations.
Since getting married and now the birth of my gorgeous baby girl I have become even more reclusive, and I think I need to kick myself into gear and do something about it.
Since I do have a bit of a problem with social interaction however, just getting out and meeting new people isn't really my thing, so I am thinking of expanding my online presence somewhat, which is just a little bit easier.

At a professional level I have started doing this a bit, with an increase in my Twitter and LinkedIn presence, and a marked increase in blogging. I would like to become more involved in PerthDotNet but as my wife works part time retail, Thursdays are out of the question for any sort of meet up.

The other area that I am thinking of using to increase my social interaction is through gaming communities. I have always been an MMO whore, from UO, EQ and DAOC in the early days, to SW:G, WoW, EQ2, DAOC, W:AR, and Eve Online more recently (yep, DAOC is there twice, i've been back to that game more than any other). Ironically though, despite being "MMO" games I have only ever had very limited interaction with the gaming community, with the majority of my time spent solo, or in the company of my RL friends. On the opposite scale, a close friend who has always suffered from social anxiety far worse than I ever did was really dedicated to the community in the MMOs we played.

The Eve community on Ars Technica was really the first time I had ever really tried to be part of a gaming community on my own. Unfortunately playing Eve with limited time commitments is an effort in futility, especially in a large 0.0 guild in a low population timezone. Whether I try and become more involved in Eve or pick up a new game such as SW:TOR, I really need to try and become a functional member of a community in the game otherwise I will end up continuing to be a hermit and end up back to where I am now.

Hopefully being part of both a professional and gaming community will help improve my communication and organisation skills, but mostly will get me back into interacting with people and becoming less of a hermit.

p.s. personal blogging is much harder than technical blogging...

Friday, November 4, 2011

Moq - Multiple Calls

I previously had the assumption that Moq allowed for Ordered setups, which was apparently mistaken. This must have been in TypeMock or another tool I looked at in the past.

So, I wanted to do three 'boundary value' calls to my service and return a different value from my repository for each call. Now I could do this as three 'setups' with the fixed paramter values, or three separate setup/execute phases, but I wanted a better way that meets the standard setup/execute/verify testing pattern.

Thanks to this blog I have a nice solution.


_hydrantDbSetMoq.Setup(x => x.GetSingle<Hydrant>(It.IsAny<Expression<Func<Hydrant>>>(), It.IsAny<IEnumerable<string>>(), It.IsAny<bool>())).Returns(
new Queue<Hydrant>(new[] { new Hydrant() { HydrantID = 100 }, new Hydrant() { HydrantID = 0 }, new Hydrant() { HydrantID = 0 } }).Dequeue
);

Hydrant actual1 = service.GetHydrant(100);
Hydrant actual2 = service.GetHydrant(-1);
Hydrant actual3 = service.GetHydrant(int.MaxValue);



And each successive call to getHydrant will return the next value in the queue.

Thursday, November 3, 2011

Mocked Repository and Generic Constraints

So, a productive couple of days - three issues resolved.

Reinstated a Repository - Moq cannot mock EF IDbSet so I decided that bringing the repository back would be a good idea. Example unit test below:

[TestMethod]
public void ListInventoryTest()
{
Mock<IDbContext> context = new Mock<IDbContext>();
Mock<AssetRepository> assetRepository = new Mock<AssetRepository>(context.Object);
Mock<StockpileRepository> stockpileRepository = new Mock<StockpileRepository>(context.Object);
List<Asset> assets = new List<Asset>();
assets.Add(new Asset() { AssetId = 1 });
assets.Add(new Asset() { AssetId = 2 });

Stockpile stockpile = new Stockpile() { StockPileId = 1, Assets = assets };

//assetRepository.Setup(x=>x.GetSingle(It.IsAny<expression<func<asset, bool="">>>())).Returns(asset);<expression<func<asset,>
stockpileRepository.Setup(x => x.GetSingle(It.IsAny<Expression<Func<Stockpile, bool>>>(), It.IsAny<IEnumerable<string>>(), It.IsAny<bool>())).Returns(stockpile);
var inventoryService = new InventoryService( stockpileRepository.Object, assetRepository.Object );
List<Asset> rv = inventoryService.ListInventory("Hailes", "Jita01");
Assert.IsNotNull(rv);
Assert.IsTrue(rv.Count == 2);
}
Then, now that I had a repository I could add a Null Object pattern solution to my repository, which was a bit tricker than I expected. In order to create a new T in the generic method, I needed to include a generic constraint to ensure T had a blank constructor.

public virtual T GetSingle<T>(Expression<Func<T, bool>><func whereClause, IEnumerable<string> customIncludes = null, bool overrideDefaultIncludes = false) where T : new()<string><func
{
IQueryable query = (IQueryable)this.ApplyIncludesToSet(customIncludes, overrideDefaultIncludes);
T val = query.SingleOrDefault(whereClause);
if (val == null)
{
val = new T();
}
return val;
}
The final issue I resolved was picking an appropriate lifetime manager for the EF DbContext when running in an 'application' context. Using the PerResolveLifetimeManager ensures that when resolving a class, any common Dependency in the entire resolve pat are shared - this means that a service with two repository dependencies, which both depend on a dbContext, will both use the same dbContext when the service is resolved - yay. This does exactly what I want it to, each operation should use a new service instance, which will use a single dbContext across all repository actions within that method.

So yeah, productive (and thanks to @wolfbyte for the generic constraint tip).

Next job to flesh out my unit tests, and continue on the functionality, as this covered the majority of my architecture issues.

Tuesday, November 1, 2011

Unit Testing, Moq, EF, and Repositories

 
Well, I have just started a small (8-12 week / 1 resource) project using an unfinished version of our in-house framework for some parts of it. In the process I want to ensure that I integrate some key design patterns (null object, repository, and unit of work) and full unit testing on the service implementation. This will hopefully help alleviate the pain of working with DotNetNuke, cross-application dependencies, and webforms.

So my first step was to property expose services from the dependent application as this is a major point of failure in other systems that use this application, which was pretty straight forward as the application design is not too bad. As this is a shared dependency on the DotNetNuke instance, I did not need to expose this as a WCF service, but could easily change it in the future if necessary. The new service interface will help prevent changes in the core application from breaking the dependent application, as any changes will be reflected as build failures in the service class, highlighting this to the developers and ensuring they either make the change to not break the interface, or let all consumers of this service know there is a breaking update and plan appropriate changes. This is a key issue encountered when services and application references are not well defined, and has caused a number of deployment issues at my current client.

The guts of this post however is to discuss my plan for unit testing, and how I had to rethink my previous statement of going ‘repository-less’. I previously discussed the removal of the repository from the framework and using the DbSet functionality in the EF context as the repository pattern. This worked really well, until I decided to do some unit tests.
I decided to use a mocking library in my unit tests specifically to ensure I was performing appropriately isolated tests, and to reduce the impact of managing test data. I had previously looked at Moles (Microsoft stubbing tool), but it always seemed so cumbersome and confusing, so I picked up Moq instead. I really like the Moq usage pattern, and so I thought it would be a good fit.

So, the plan was to use Moq to create mocks of the repository functions that act in predictable and repeatable ways, which means we can run the service and test that the service behaves as we expect.

An example is given below – in this example I created a service to get a list of ‘stations’ from the dependent application. Since I am testing my service, I want to Mock the dependent application service to act predictably, so I can ensure that my service acts the way I want it to (we are not performing end-to-end integration testing, so we don’t want to rely on the dependent application succeeding or failing at this point)


//when we call ‘GetStations’ with a parameter of 0, our mocked service throws an exception – I know the dependent service reacts in this way, so I can ensure this is integrated in my test
_samsServiceMoq.Setup(x => x.GetStations(0)).Throws();
//when we call ‘GetStations’ with a parameter of -1, our mocked service returns no results
_samsServiceMoq.Setup(x => x.GetStations(-1)).Returns(new List());
//when we call ‘GetStations’ with a parameter of 1, our mocked service returns a list with one item in it
_samsServiceMoq.Setup(x => x.GetStations(1)).Returns(new List() { new Unit(){ UnitID = "100" } });
 
UserService target = new
UserService(_samsServiceMoq.Object); //create an instance of my service, and pass in the mocked dependent service
List actual1;
List actual2;
List actual3;
actual1 = target.GetStations(-1); //execute the service method with the specified parameter
actual2 = target.GetStations(1); //execute the service method with the specified parameter
actual3 = target.GetStations(0); //execute the service method with the specified parameter
_samsServiceMoq.VerifyAll();
//check whether the mocked service methods were called in the execution of our tests – this is useful to ensure that your service method is calling the expected mocked method with the expected parameters.
//check the results from the service to ensure they match what you expect (based on the response from the mocked service)
Assert.IsNotNull(actual1);
Assert.IsNotNull(actual2);
Assert.IsNotNull(actual3);
Assert.AreEqual(0, actual1.Count);
Assert.AreEqual(1, actual2.Count);
Assert.AreEqual("100", actual2[0].UnitID);
Assert.AreEqual(0, actual3.Count);

The above example shows how you can configure a test without worrying about the dependent services, so you can test only the functionality in your service. You will also note that the service itself needs to be designed so that all dependencies are passed to the service, instead of created in the service (this is a key point in ensuring testability of components, all dependencies must be passed to the object). If we did not do this, we could never mock the dependent service, which means we would need to set up the test to ensure the dependent service responds appropriately (configure the dependency, and know/configure sample data that the dependency will respond to).
This works really well, I can test my (admittedly very simple) service without caring about configuring the dependent service. However doing the same thing on an EF repository instead of the dependent service does not work so well. The code below should work, but doesn’t due to limitations in EF/C#/Moq.


_hydrantContextMoq.Setup(x=>x.Hydrants).Returns(_hydrantDbSetMoq.Object);
_hydrantDbSetMoq.Setup(x => x.ToList()).Returns(new List() { new Hydrant() });
HydrantService service = new HydrantService(_hydrantContextMoq.Object);
List actual;
actual = service.GetHydrantList();
_hydrantContextMoq.VerifyAll();
_hydrantDbSetMoq.VerifyAll();
Assert.IsTrue(actual.Count == 1);

Here I am mocking my DbContext to return a mocked IDbSet, and mocking the IDbSet.ToList() to return a list of Hydrants with 1 item. This way I can test my service so that calling getHydrantList on my service returns the single length list. Unfortunately, IDbSet.ToList() is not a mockable method (it is actually an extension method) which means it is not possible to set up a mock for this method. Since my service is using this method, I cannot test my service in isolation of the database.


This is where the Repository comes in. Instead of using the IDbSet.ToList() directly, I would use a Repository GetAll() method which abstracts the call to the underlying DbSet method. As the repository is just another dependency on the service, we can mock this instead of the EF IDbSet, and hence have an appropriately testable service. We will also then have the ability to ensure that the repository supports the null object pattern, so a call to the IDbSet that may return null (such as a find() with an invalid key) can return an appropriate null object to the service, so the service, and all clients, know it will never receive a null as the result of a service operation.

So, big backtrack on the framework repository, and big kudos to Moq for making testing easier (at least for my simple examples so far).

Monday, October 31, 2011

Distractions

Yes, I have been slack lately, but I was going to get back into things, promise. The nudge from a colleague had nothing to do with it.

I have a soft spot for RPGs and Turn-Based Strategy games, and with the cheap Civ5 purchase a little while back, and pulling out my PSP for some Final Fantasy Tactics in the last couple of weeks, I haven't done much of anything for about a month. I like to think of these distractions as a necessary break when working on projects outside of work, but I do get sucked in a bit too much sometimes.

So, I have a handful of things I wanted to sort out with my Market game.

Framework / Architecture


  • Remove the AoP 'Unit of Work' implementation - this is pretty much done, I just need to formalise the new pattern for the UnitOfWork (single EF context/unit of work for each 'public' business method, and a single usage business service)

  • Restore the repository layer - specifically to assist with unit testing (EF/Queryable methods are not mockable, at least using moq).

  • The Repository has jumped back into my consciousness for two reasons - one, on a new small project I kicked off I plan on doing thorough unit testing, and found that the base EF IDbSet functions cannot be mocked. and two - implementing a null object pattern using EF is not simple, but implementing this logic in the repository is pretty simple.

  • Investigation on a dual nHibernate / EF implementation - see how much effort is involved in creating an nHibernateRepository

  • Investigation into AutoFac for Dependency Injection / IoC - problems with Unity lifetime behaviours and Bootstrapping may be improved with AutoFac.

  • Modify the application actions to use a command pattern, and introduce a server queue for processing.

  • Revisit the timed action services (server thinking / working) to produce a more flexible solution

Short Term Functionality



  • Implement base (atomic) producer AI

  • Implement complex (multiple ingredient) producer AI

  • Implement producer (basic and complex) trading AI - buy (ingredients) and sell (created items) orders, basic market analysis/P&L.

  • Add market transactions

  • Implement a lightswitch asset management application

  • Add ships/capacity and item volume

  • Add ship cargo

  • Add pathfinding

  • Add movement

  • Add Trading AI (buy/move/sell) - include improved market analysis

So yeah, i should get my ass into gear.

Thursday, October 13, 2011

Google, Amazon, Dog Food, and Loyalty

So there's two things I take out of the Steve Yegge Google rant (https://plus.google.com/112678702228711889851/posts/eVeouesvaVX#112678702228711889851/posts/eVeouesvaVX) that I had already been thinking about recently.

The first is the idea of the "Platform" and how the Amazon SOA mandate led to the position they stand today. I had no idea they offered so many services, but you can clearly see how each of their offerings has grown from their internal systems being designed as independent hosted components (even down to their payments system). You can see the "Eat your own Dog Food" approach has clearly paid off, as amazon can expose these proprietary systems as consumable services, monetizing them instead of simply consuming them as part of their own needs. This is an extreme example that progressed over the course of years, but it does highlight the capabilities that SOA can offer. If you build for enterprise integration and SOA, your components can become much more than the sum of their parts.

The second concept his post highlighted is the idea of company loyalty, and a love for your work. Steve clearly loves google and has a passion for not only what he does at Google, but what Google does in the broader scheme of things. I think for all the perks that Google offers, this level of loyalty stems from much more than just the money thrown around.

In the past I have worked at a company that I really loved, and while I was paid fairly well, and we had pretty good perks, it was more than this that really made the difference compared to where I am now. We were all treated with respect and acknowledged as key contributors in the company not just a resource, remunerated according to our capabilites, and as a team we all had a passion for what we were doing. This last point is a key item in what made the work environment so outstanding. We felt like we were doing something worthwhile, always pushing each other to improve and grow, and were all happy doing what we were doing.

I miss that high level of motivation from the teams I work with, but I recognise that this was an exceptional workplace and very little will ever compare. Reading the post drove home how great the workplace was.