bling.github.io

This blog has relocated to bling.github.io.

Friday, August 21, 2009

Session management with NHibernate and Autofac: Corollary

Ooops, I forgot to mention that it's easily mockable as well.
public class UserService : IUserService {
  public UserService(ISessionFactory factory, UsersRepositoryFactory usersFactory) { ... }
}
So that's the basic thing right. So now, with Moq, we can do this:
var mockUserRepo = new Mock<IUsersRepository>();
mockUserRepo.Setup(x => x.GetUser(It.IsAny<string>())).Returns(() => someUser);

var userService = new UserService(..., x => mockUserRepo.Object);
So what I've basically done is insert a lambda expression into the constructor, which is the delegate, which always returns my mock repository. Pretty nifty methinks!

Thursday, August 20, 2009

Session management with NHibernate and Autofac

NHibernate is a beast let me tell you! I think I already mentioned this in the previous post, but NHibernate definitely has a VERY high learning curve. If it wasn't for FluentNHibernate I'd probably still be struggling with XML mapping files right now.

But anywho, it didn't take long for me to run into very many problems with NHibernate. It's not really NHibernate's fault, but more of maybe I'm trying to use the wrong tool for the job.

I'm using DDD for my project, and there's a clear separation between the client and the domain. I got lazy and I didn't make any DTOs for my entities, and just used the [DataContract] and [DataMember] to have WCF automatically generated "DTO"s for me (and in the options turn OFF reusing assemblies).

(Disclaimer: I am *not* by any means knowledgeable about NHibernate, but maybe, just maybe what I say here might point other people in the right direction)

OK, all is good. I can store my entities in the database, I can read them back. So I fire up my client and read some users, and it blows up. NHibernate by default lazy loads everything. Here's what I originally had in my UsersRepository
public IEnumerable<User> GetAll() {
using (var session = _factory.OpenSession())
return session.CreateCriteria<User>().List<User>();
}

It looks pretty innocent. But it blows up. Why? If Users has a collection of other entities (which mine did), they are not loaded with the above code. They are loaded on-demand, i.e. lazy loaded. So when my WCF service finally returns the objects and serializes them, it pukes and throws an exception because the session was long closed already.

Easy solution was to Not.LazyLoad() all my collections. Now here's what I'm thinking I might not be using the right tool for the job because I am purposely disabling one of the key features of NHibernate. By default, caching is always enabled, and I couldn't find anywhere how to globally turn it off. You must go class by class.

OK, so on to my next problem. I soon ran into issues with entities not being unique. I would have code like this in my UserService:
public void AddProduct(string username, Guid productId) {
var user = _usersRepository.GetUser(username);
var product = _productRepository.GetProduct(productId);
user.Products.Add(product);
_usersRepository.Store(user);
}

Again, this puked. The problem here was after my GetUser call, inside my repository, like my first example, I had a using(session), which closed when the method ended. Shortly after, I am trying to update the same user, but with a *different* session. NHibernate doesn't like this, an NHibernate.NonUniqueObjectException is thrown, and I had a new problem to deal with.

It became clear I had to actively manage the sessions somehow, and the best place would be to have them in my services, which typically each method had a "unit of work" placed on them.

So the goal I wanted to accomplish was to initiate a new session at the beginning of a service method, call a repository multiple times, close the session, and then exit the method.

So how can we achieve that?

I thought of a couple things, and the first thing I did actually was to use AOP style and use Autofac with Castle.DynamicProxy. I created an interceptor for my service, and before invocation I opened a session, then manually called a property setter for a CurrentSession, and after invocation close the session.

It did the job, but had some problems:
a) It did a little too much black magic for me. All methods got intercepted.
b) I still had to manually set the CurrentSession property of my repositories. Sooner or later I'm sure to run in the threading problems.

After I got that half working I scrapped it and tried to come up with something better. This is what I came up with:
public delegate IUsersRepository UsersRepositoryFactory(ISession session);

public class UserService : IUserService {
public UserService(ISessionFactory factory, UsersRepositoryFactory usersFactory) { ... }
}

public class UsersRepository : IUsersRepository {
public UsersRepository(ISession session) { ... }
}

Now, when I call a method on my UserService, I do this:
public void AddProduct(string username, Guid productId) {
using (var session = _factory.OpenSession()) {
var userRepo = _userRepoFactory(session);
var productRepo = _productFactory(session);
...
}
}

And, of course, the Autofac code:
b.Register<UsersRepository>().As<IUsersRepository>().FactoryScoped();
b.RegisterGeneratedFactory<UsersRepositoryFactory>();

More details on the delegate factory here. But basically, with Autofac I have told it to inject delegates into my UserService, and those delegates can create new instances of my user repository by passing in the current session.

You'll also notice I had a products repository as well. With these delegate factories I can create up multiple repositories on the fly with the same session (and all the good NHibernate stuff that comes with that).

Sure, there's a whole bunch of using(var session) boilerplate now, but it's explicit, clear, and allows for a lot of fine-grained control.

EDIT: I have since dropped this approach and I'm currently injecting ISessions into my constructors by using Autofac's container-scope (something that took me a while to understand).

Tuesday, August 18, 2009

Goodbye db4o, Hello ORM

It's unfortunate that I have to remove db4o from my project, but I can't say this was unexpected. The CTO finally came to me today to voice his concerns on using an object database rather than a relational database. As typical of many organizations, we have a database team dedicated to maintaining the integrity and performance of our main product. We are also stored procedure happy and every write and read operation goes through a stored procedure....so you can say I was pretty gutsy to even consider using an object database ;-) It was fun nonetheless... Sooooo....which ORM to use? I've already read of all the things about the Entity Framework already, so I didn't even bother considering it. Choices came down to just a few: a) Castle.ActiveRecord b) Fluent NHibernate c) SubSonic I've initially started with Fluent NHibernate. The main reason is because it's got really good documentation for beginners like me who've never used NHibernate, and has more configuration options via code. Even so, it didn't take long for me to run into gazillions of mapping errors though :-[ I'm still undecided whether I prefer ClassMap<> or ActiveRecord attributes though... I started porting all my repositories to using NHibernate, and for the most part it wasn't too bad. I've learned some things along the way like lazy loading and cascading, but the conclusion is having Fluent NHibernate with pretty code completion isn't going to prevent the need to actually learn NHibernate the old-fashioned way, although it definitely got me up and running a lot faster. I'll probably write up a quick repository implementation with SubSonic as well as part of my prototype to see which I like. SubSonic definitely looks more 'hip' with it's very flashy and web 2.0ey looking website :)

Saturday, August 15, 2009

DDD, TDD, Enterprise Library, Autofac, and Lokad.Shared libs!

So my project has been chuggin along quite nicely, and gave my CTO a quick look over the design of my project of which he was very impressed...I'm glad I spent all that time reading up on DDD, BDD, TDD, and listening to all the ALT.NET podcasts. I've learned SOOOOO much in the past month it is ridiculous, mostly thanks to coming across ALT.NET, and then reading everything linked from that source. I can honestly say I'm 100% sold on the TDD approach. Initially, after reading about it I was like, hmmm, yeah, I can see that working, but writing tests first kinda seems dumb and redundant. After all, obviously you know the tests will pass because you wrote them!! Then...I saw the light!!! I'm currently prototyping my project, but since I live in the real world I can reasonably assume the prototype will become the real thing. But that's not really an issue having designed everything with DDD and DI. Once the prototype is done, we can optionally replace the implementation, change the IoC wiring up, and voila, it just works (because we had all those tests written). Another design choice for the prototype I made was to use DB4O rather than SQL Server. DDD emphasizes very much on storing aggregate roots in repositories, and let's be honest, object databases work ridiculously well with storing domain entities. So not only can I speed up development in my prototype by having all repositories go to a DB4O backing store, if it's decided we need to change to a relational database, boom, I just need to reimplement all my repositories with NHibernate. And just to drive home how easy DB4O is, literally, this is what you need to do to store a User in the database.
using (IObjectContainer c = Db4oFactory.OpenFile("database.db"))
{
  c.Store(user);
}
Seriously!!! It IS that easy! But back to why I'm sold on TDD. Originally, I had IUsersRepository modeled something like this:
User GetUserByName(string userName);
User GetUserById(Guid id);
User GetUserByFirstName(string firstName);
And then I realized, it's a total pain in the butt to be adding all these methods because once the method call reaches the DB4O container, I need to pass in a predicate for the query. So I thought, I'll just pass the predicate directly to DB4O. I changed all my repositories (I had 4 at the time), to do this instead:
User GetUser(Predicate<User> condition);
So now I can simply do this:
var user = usersRepository.GetUser(x => x.UserName == userName);
I've converted 3 methods (and potentially more) into a single method that is very expressive and easy to read (thank you lambdas!). And then I reran all my tests and they passed....which leads to the following conclusion: TDD lets you refactor with confidence! Oh wait, I mentioned Autofac and Lokad.Shared libs in this blog post didn't I.... To start...my project has removed all dependencies on the Enterprise Library. In my previous post I mentioned how Unity wasn't as mature as other frameworks. Well, it appears that the Logging Block and/or the Exception Handling Block has a dependency on Unity. I definitely did not like having 2 IoC containers in my bin directory, so I decided maybe I should just ditch the entire thing. Honestly, I didn't really like the EntLib anyways....the logging block requires the use of a static class Logger (tight coupling), and the exception block needs a try/catch/handle for any exception you want to handle, again with a static class ExceptionPolicy (more tight coupling!!!). So now it was a matter of finding a replacement. There really was only 2 choices: the Castle Stack, or Autofac+Lokad.Shared. I was not very impressed with the lack of documentation on the Castle Validator component (or even where to download a binary of it). Also, I'm really not a big fan of attributes on parameters. So what's left is Autofac and Lokad.Shared. I chose Autofac mainly because I love its lambda syntax (and the included performance benefit). But of more concern is Lokad.Shared. a) It is basically written by 1 guy b) It doesn't have community inertia But after reading the examples here and here I didn't have a choice! It is just too damn nice! Comparing code I'm writing today with code I wrote 3 months ago is like light and day....on different planets. And since I'm very link happy today, check out this awesome add-on called Studio Tools. It's free, only 1.9 megs and has the most impressive and blazing fast file/class/symbol search I've ever seen.

Saturday, August 8, 2009

Dynamic proxies

Life has sure been a roller coaster lately ever since I started working on my new project. I've learned a lot about WCF in the past week. There's really nothing that can teach you faster than trying something out yourself. I've joined the ranks of countless others who have had to deal with implementing service behaviors to handle WCF exceptions (because by default thrown exceptions fault the communication channel), realized that WCF proxy clients breaks the 'using' keyword because someone thought it was a good idea to throw exceptions in Dispose(), and even Unity's InterfaceInterceptor not supporting more than 1 interface! But now that we're talking about proxies, I've been thinking for a while about switching out Unity with a more mature IoC container like Windsor or StructureMap. There are little touches that other containers have that I miss in Unity. For example, auto-wiring. But then again, the integration that Unity has with the rest of the Enterprise Library is very nice, of which I'm using the Logging and Exception Policy blocks, so it made sense in a way that everything in my bin folder just had Microsoft.Practices.*.dll But now I'm seriously reconsidering.
public interface ITestService {
  int Count { get; set; }
  void DoWork();
  bool ShouldDoWork();
}
public class TestService : ITestService {
  public int Count { get; set; }
  public void DoWork() { ++Count; }
  bool ShouldDoWork() { return true; }
}
public void HowDoTheyCompare() {
  var unity = (ITestService)new Microsoft.Practices.Unity.InterceptionExtension.InterfaceInterceptor()
                   .CreateProxy(typeof(ITestService), new TestService());
  var castle = new Castle.DynamicProxy.ProxyGenerator()
                   .CreateInterfaceProxyWithTarget<ITestService>(new TestService());

  Thread.Sleep(1000);

  Stopwatch sw = new Stopwatch();
  sw.Start();
  for (int i = 0; i < 1000000; ++i) { if (unity.ShouldDoWork()) unity.DoWork(); }
  sw.Stop();
  Console.WriteLine("unity: " + sw.ElapsedMilliseconds);
  sw.Reset();
  sw.Start();
  for (int i = 0; i < 1000000; ++i) { if (castle.ShouldDoWork()) castle.DoWork(); }
  sw.Stop();
  Console.WriteLine("castle: " + sw.ElapsedMilliseconds);
}
Results? unity: 1787 castle: 136 From this test it looks like the Unity interception is 13x slower....but wait! I mentioned before that Unity has a bug where it can only proxy one interface....so to resolve that we would need to use the TransparentProxyInterceptor. Let's change it and test again... unity: 30462 castle: 142 Hmmmm....214x slower. I guess we can try the VirtualMethodInterceptor for completeness. After making all methods virtual, here's the results. unity: 3843 castle: 132 Still 29x slower. Whatever DynamicProxy is doing...it's orders of magnitude faster than what Unity's doing.

Thursday, August 6, 2009

Who woulda thought, IList<> kills WCF

It can't be that hard!!! I keep telling myself this. I'm writing a WCF application right now and I've been running into loads of problems trying to configure things. ABC right? Set my address, contract, and binding....how hard can it be?? Why is a horrible ExecutionEngineException being thrown and taking down IIS with it??? http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=433569 Turns out you can't have an IList<> of DataContracts.