Make your project pluggable with StructureMap

Posted on November 11th, 2009 in Design, StructureMap by Jon Kruger

UPDATE: This post has been updated to account for the StructureMap API changes that happened sometime around StructureMap 2.5.4.

We all know that StructureMap is great for implementing dependency injection in your application, making your app more testable, and all that. But StructureMap can do so much more than that. StructureMap can help you create pluggable project architectures that can allow you easily modify how your application works in certain situations with minimal to no configuration.

layersLet me explain. Most people have some kind of layered setup in their projects. The basic architecture is 3 tiers — a UI layer, a business layer, and a data access layer.

Entity objects are going to flow through these layers. You will load, save, and delete entities. And in most cases, the way that you load, save, and delete these entities will be the same — but not always the same.

What we want to do is write code to handle the normal entities and write it just once. If we need to modify how things are done for a certain entity, then we’ll write code for that. By doing it this way, we should have little or no code duplication.

The diagram on the right shows our project structure. You will notice that we have some generic interfaces defined in the business layer and data access layer. That classes that implement these interfaces will perform the specified actions using an entity (the generic parameter T in each interface).

Here’s an example. The IRepository<T> interface contains methods that will talk to the database. I will create a concrete class called Repository<T> that implements the standard method of talking to the database. This is how most of our entities will be loaded, saved, and deleted.

public interface IRepository<T> where T : class
{
    T Get(long id);
    IList<T> GetAll();
    void Save(T target);
    void Delete(T target);
}
 
public class Repository<T> : IRepository<T> where T : class
{
    public T Get(long id)
    {
        // do stuff here
    }
 
    public IList<T> GetAll()
    {
        // do stuff here
    }
 
    public void Save(T target)
    {
        // do stuff here
    }
 
    public void Delete(T target)
    {
        // do stuff here
    }
}

Let’s say that I have a Customer entity that is persisted to a different database than the rest of the application. I now have a special case where I need to write custom repository code for a Customer. So I’ll make a class called CustomerRepository and have it implement IRepository<Customer>.

public class CustomerRepository : IRepository<Customer>
{
    public Customer Get(long id)
    {
        // do custom stuff here
    }
 
    public IList<Customer> GetAll()
    {
        // do custom stuff here
    }
 
    public void Save(Customer target)
    {
        // do custom stuff here
    }
 
    public void Delete(Customer target)
    {
        // do custom stuff here
    }
}

Here’s where StructureMap comes in. I’m going to configure StructureMap so that I can ask for IRepository<T> for some entity T and it will give me back the correct concrete class. This means:

IRepository<Product> maps to Repository<Product>
IRepository<Order> maps to Repository<Order>
IRepository<WhateverOtherEntity> maps to Repository<WhateverOtherEntity>
IRepository<Customer> maps to CustomerRepository (because CustomerRepository implements IRepository<Customer>)

Look at how easy this is going to be! I’m not going to have to do any extra configuration or wiring up to change how Customer entities are persisted. I’m not going to write any extra plumbing code, I’m just going to create the CustomerRepository class and implement an interface, and now my app deals with Customer objects differently.

Obviously there is some fancy plumbing going on behind the scenes, so let’s see how we set this up.

It’s really not that hard, actually, because most of the hard work is done by StructureMap. We just have to do some simple configuration.

Here’s how we initialize StructureMap:

public class StandardStructureMapConfiguration
{
    public void Configure()
    {
        ObjectFactory.Initialize(x =>
        {
            x.Scan(scan =>
            {
                // Automatically maps interface IXyz to class Xyz
                scan.WithDefaultConventions();
                scan.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
                scan.ConnectImplementationsToTypesClosing(typeof(IGetObjectService<>));
                scan.ConnectImplementationsToTypesClosing(typeof(ISaveObjectService<>));
                scan.ConnectImplementationsToTypesClosing(typeof(IDeleteObjectService<>));
 
                scan.Assembly(GetType().Assembly);
            });
 
            x.For(typeof(IRepository<>)).Use(typeof(Repository<>));
            x.For(typeof(IGetObjectService<>)).Use(typeof(GetObjectService<>));
            x.For(typeof(ISaveObjectService<>)).Use(typeof(SaveObjectService<>));
            x.For(typeof(IDeleteObjectService<>)).Use(typeof(DeleteObjectService<>));
        });
    }
}

Let’s break this down and go over what I’m doing here.

scan.WithDefaultConventions();

This tells StructureMap to automatically map an interface IXyz to class Xyz. Most of the time, the names of your interfaces are just the concrete class with an “I” slapped on the front. This only applies to non-generic classes, so this isn’t necessarily helping us with our IRepository<T> example, but I do it on every project, so I thought I’d throw it in.

scan.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
scan.ConnectImplementationsToTypesClosing(typeof(IGetObjectService<>));
scan.ConnectImplementationsToTypesClosing(typeof(ISaveObjectService<>));
scan.ConnectImplementationsToTypesClosing(typeof(IDeleteObjectService<>));

We don’t just want to use the default conventions, we want to tell StructureMap to map concrete classes that implement generic interfaces. Basically all we’re doing here is telling StructureMap that if I have a custom concrete class that implements one of these generic interfaces, we want to automatically wire those up.

scan.AssemblyContainingType(GetType().Assembly);

We want StructureMap to look inside the specified assembly and apply the conventions to the types in this assembly. You can also do scan.AssemblyContainingType<T>.

x.For(typeof(IRepository<>)).Use(typeof(Repository<>));
x.For(typeof(IGetObjectService<>)).Use(typeof(GetObjectService<>));
x.For(typeof(ISaveObjectService<>)).Use(typeof(SaveObjectService<>));
x.For(typeof(IDeleteObjectService<>)).Use(typeof(DeleteObjectService<>));

Here we are wiring up the generic interfaces to the default concrete implementations of each interface. This is for the 95% of the time when we’re using the normal way of doing these things.

StructureMap needs to be initialized whenever your application starts (Program.cs for WinForms, App.xaml.cs for WPF, Global.asax Application_Start() for web apps). So in this case, I would new up an instance of the StandardStructureMapConfiguration class that I created here and call the Configure() method, which would do all of the ObjectFactory.Initialize() stuff.

I created a small sample project with this code. This is really easy to implement and it makes development a lot easier by reduces the amount of tedious plumbing code that you need to write.


Kick It on DotNetKicks.com

Why I don’t put load/save/delete methods on entity objects

Posted on November 5th, 2009 in Design, OOP by Jon Kruger

Someone asked me the other day if putting Load(), Save(), and Delete() methods in entity objects is a bad thing. While I tried my best to explain why I don’t put these methods on entities, I thought it was worthy of a blog post.

I am a .NET developer, so I’m going to answer the question with how I would do it in .NET. If you’re working in a dynamic language like Ruby, things are certainly different and you don’t have all of the limitations that you have in .NET. So what I’m about to say really only applies to the static-typed languages (.NET, Java, C++, etc.).

First of all, I am writing unit tests, which means that I’m using concepts like dependency injection. Someone who doesn’t write unit tests or use dependency injection might not see value in structuring their code the way I structure it. But the arguments here only partially have to do with testability.

Let’s say that I have these entities in my application — Product, State, Country, Customer, Order. In this list I have some things that change often (Customer, Order) and some things that won’t change often (Product, State, Country). So let’s say that I decide that I’m going to cache the entities that don’t change often.

Let’s think of this in terms of loading, saving, and deleting. When I load them, I’m going to check the cache first. When I save them, I’m going to save the object to the cache as well as the database. When I delete them, I’m going to remove them from the cache. I’m going to change how these types of entities are loaded, saved, and deleted.

Now let’s imagine that my entities had methods like Load(), Save(), and Delete(). I would have to implement the special cached loading, saving, and deleting in three places - Product, State, and Country (and whatever other cacheable entities that I have). Any time you have to copy and paste code you should start to wonder if something is wrong.

In this case, I might deduce that the way to solve the duplication would be to split out the code that loads, saves, and deletes cacheable entities into some other class that is outside of the entity class. These classes would be powerful because they aren’t just acting an individual entity type, they are acting on certain kinds of entities. Maybe you specify that an entity is cacheable by having it implement and interface or maybe you decorate it with an attribute.

Now when you have another cacheable entity, all you have to do is implement the right interface or put an attribute on the entity class and it will automatically work with the cache!

This is a good example of the difference between object-oriented code and procedural code. We want to do more object-oriented programming and less procedural programming because object-oriented code is more testable, flexible, and reusable.

There are also testability reasons for not putting Load(), Save(), and Delete() on entity objects. If you don’t understand dependency injection, you should go read about it first so that this makes more sense.

When using dependency injection, you take in dependent classes through the constructor, but you don’t do this with entity objects because entity objects do not have dependencies. Entity objects define what the model is, and other classes (”domain services”) define how the entities work together.

Earlier in the post I talked about how I would create a class that knows how to save cacheable entities. If I had a Save() method on my entity class, I would need to call this other class (a dependency) from my entity’s Save() method. But remember, entities don’t take in dependencies, and I don’t want to new up the class that does the saving because now I can’t mock that class in a unit test.

You might be reading this and it might not make a whole lot of sense, but that’s OK. This is much different from how some people have written code for a long time, and they don’t teach you this type of stuff in school. But it’s always a good idea to question why things are done certain ways and maybe you’ll learn something new that can really help you out.


Kick It on DotNetKicks.com

Why I don’t like hand rolled data access layers

Posted on October 13th, 2009 in Design, Fluent NHibernate, NHibernate by Jon Kruger

In my last post, I mentioned that I think that hand rolled data access layers using stored procedures are a bad thing, and one of my co-workers asked me to elaborate.

The main reason that I don’t like hand rolled data access layers is that by writing your own DAL, you are basically reimplementing a solved problem. Think about all of the things you have worry about if you write your own DAL:

  • Creating the CRUD stored procs
  • Writing ADO.NET code to call the stored procs
  • Figuring out which entities are dirty and need to be saved, and which properties have changed
  • What relationships do you load when you load an entity from the database? How do you do lazy loading of relationships?
  • Writing tests to test all of this custom code that you have to write

There are numerous object-relational mapping (ORM) tools out there which take care of all of this. NHibernate is my favorite (more specifically, Fluent NHibernate). NHibernate has been around for several years and is very mature. There are ORMs from Microsoft (LINQ to SQL, Entity Framework), and numerous other ORMs out there.

These ORMs have thousands of people using them, so they have been well tested and have proven over time to be very effective at what they do. Countless hours have gone into the development, design, and testing of these ORMs.

Think about what you are trying to do by writing your own hand rolled data access layer. Who are you to think that you can do a better job in a short amount of time than the people who developed these mature solutions over several years? Data access is a very complicated thing to try and implement, and some of the most painful code that I’ve ever had to deal with was found in someone’s hand rolled data access layer.

Here’s the thing — a large percentage of your data access is vanilla loading and saving of objects from the database. In these cases, performance is not a concern and you do not need any special queries in order to optimize the loading and saving of these objects.

For a very small percentage of your data access, performance may be a concern and you may need to use custom stored procedures. So in these cases, you can bypass the ORM and write your stored procedures and custom code in order to optimize the loading and saving of these specific objects.

If you use stored procedures and custom code, you have more control over things. This also comes with a cost (longer time to develop). If you are accepting this cost for cases where you don’t need to optimize the data access, I would say that you’ve wasted time on premature optimization, not to mention that you’ve probably had to spend time implementing all of that data access code.

I would rather use an ORM that has implemented everything that is difficult about data access. Now all I have to tell it how to map to the database (which isn’t that hard) and tell it to do things for me. With lazy loading, it won’t load entity relationships (e.g. child collections on an entity object) unless it needs to. It knows when objects are dirty and if they need to be saved or not. I have an easy hook so that I can validate entities when they are saved.

The other day I configured a cache in NHibernate in 15 minutes. With very little code I was able to set NHibernate up so that it will cache entities that don’t ever change in memory so that it doesn’t have to get to the database to get them every time. There were numerous examples on the internet telling me how to do this, and I’m extremely confident that it’s going to work (I didn’t have to write any of the difficult code for caching because NHibernate has solved that problem).

I want to write code that solves business problems. Thankfully other people have written libraries that will help me do that. So I’m going to use them.


Kick It on DotNetKicks.com

I’m speaking on SOLID at QSI Tech Night on Wed., Sept. 16

Posted on September 6th, 2009 in Design, Quality by Jon Kruger

I’ll be speaking on the SOLID software design principles at the Quick Solutions office (440 Polaris Pkwy., Suite 500, Westerville) on Wednesday, Sept. 16 from 5:30pm-to 7pm. In this talk, we’ll go through Uncle Bob’s “SOLID” software design principles, separation of concerns, a brief overview of inversion of control containers like StructureMap and Ninject, and more object-oriented goodness that will help you write better code.

There’s free food too. If you’re coming, please RSVP to amorey at quicksolutions dot com so that we can have enough food.

If you’re going to the Software Engineering 101 conference, this is basically the same talk that I’ll be giving there. So if you’re going to go to one, go to the Software Engineering conference since you’ll get lots of other good stuff there too.


Kick It on DotNetKicks.com

Software Engineering 101 Conference - Sept. 23

Posted on August 24th, 2009 in Design, TDD, unit testing by Jon Kruger

In case you haven’t heard, the Software Engineering 101 Conference is going on in Columbus on September 23. This is a one-day event where you will learn about software design topics and techniques such as object-oriented programming and the SOLID software design principles as well as a super-special hands-on test driven development session! This is all good stuff that every developer should know and it will be well worth your time. Rather than recount all the details, I’ll let you read more on Jim’s blog.

This is a FREE event, so all you have to do is ask your employer if you can go, they don’t even have to pay anything for it. I feel like I say this a lot, but these skills are essential for any software developer and have revolutionized the way that I write code.

Registration is limited, and I expect that it will fill up relatively soon, so don’t wait! You can click here to register.


Kick It on DotNetKicks.com

What should you learn next?

Posted on July 26th, 2009 in Design, TDD by Jon Kruger

Most of us at some point have decided that we want to learn some new technology. The question is what you should dive into.

When I interview people, I always ask them about new things that they have been learning, and a lot of people these days are looking into things like WPF and Silverlight. But this is not what I would pick if I were you.

If you were to ask me, instead of learning some new technology, every developer should try to become experts in software design patterns and principles and practices that will help you become a better developer with the technologies that you already know. Our industry has a much bigger need for developers that write well-designed, loosely coupled, well-tested code than we need for people with a basic knowledge of WPF or Silverlight.

Look, there’s nothing wrong with learning WPF and Silverlight, and you can make some awesome looking apps with them. But if you can learn software design patterns and practices, those will help you when using any language for the rest of your career. They will help you write less bugs, they will help you get stuff done faster, and they will help you write flexible code that can easily be changed. Who doesn’t need more of that?

Like I said, I interview people. If I interview you and you know and practice things like test-driven development, the SOLID principles, what the Law of Demeter is, and why all of this matters, then you are most likely in (as long as there isn’t something else seriously wrong with you). In my opinion (and this is just my opinion), if you want to be called a “senior developer” I would expect you to know all of these things. This is much more important than how many years of experience you have.

This may require some research and leg work on your part. I say this because in my opinion, Microsoft doesn’t not actively promote this stuff. Sure, you might find some MSDN article out there that talks about testing or patterns or something like that, but there will probably be many times more articles about Silverlight, new features in .NET 4.0, and the like. All of that stuff is good, but I feel people are skipping over the essentials. You can probably pass any number of Microsoft certification tests without knowing much about test driven development or design patterns.

This is why I identify with the ALT.NET way of thinking. ALT.NET generally believes in these principles:

1. You’re the type of developer who uses what works while keeping an eye out for a better way.
2. You reach outside the mainstream to adopt the best of any community: Open Source, Agile, Java, Ruby, etc.
3. You’re not content with the status quo. Things can always be better expressed, more elegant and simple, more mutable, higher quality, etc.
4. You know tools are great, but they only take you so far. It’s the principles and knowledge that really matter. The best tools are those that embed the knowledge and encourage the principles (e.g. Resharper.)

Promoting ALT.NET or starting some new kind of cool kids club is not the point. The point is that good software design practices and principles are very important (many would say of the utmost importance), much more important than the latest shiny new tool that is coming out. If the code you write is not well designed or well tested, that problem is not going away by moving to .NET 4.0 or Silverlight.

So if you want to learn good software patterns and practices, here’s where I would start:

  • Learn how to do test-driven development. The best way is to have someone teach you how to do it because it’s hard to just read about it and pick it up (although you’re more than welcome to try!). If you don’t have someone to teach you, hopefully the next technical conference or Day of .NET or user group you go to will have a talk on how to do TDD. Go to it. I have lots of TDD links and some practice projects here.
  • Learn the SOLID principles and why they’re important. You can go buy this book or just read everything on this page. Again, if you next conference/user group/etc. has a talk on SOLID (and a lot of them will), go to it.
  • Read some of the “classics”, like some of the books mentioned here.
  • Make sure you keep your ego in check. We should never stop learning, and should never be content with where we are now. There will always be something worth knowing that you don’t know.

Kick It on DotNetKicks.com

Don’t cheat on those small apps!

Posted on March 31st, 2009 in Design, Quality by Jon Kruger

At some point, we all have to write some small apps. I’m talking about things like…

  • Some small utility or diagnostic app
  • Something to help with your deployment process
  • Other small applications or websites (i.e. something that takes a month or less)

In these cases, we often throw good software design principles out the window. We say that we don’t need to write unit tests, we don’t need dependency injection, we can put data access code in our code-behinds, and things like that. Since it’s a small app, we think we can get away with it.

Just because your app didn’t take you long to write doesn’t mean that you get off easy. The consequences of your decisions just aren’t as severe, but that doesn’t mean that the pain is gone!

How many times have you written some small utility to help with something and then your boss sees it and really likes it, and then he asks you to add more functionality to it. Eventually you’ve spent a couple months on the app. If you cheated at the beginning, that code is going to hard to change and it’s going to start becoming more of a pain.

Maybe you’re writing a console app to help with your deployment process. Now this code better work, because if it doesn’t, your app might not deploy correctly. This is very important code! Doesn’t code this important warrant some extra attention (i.e. tests)?

Look, I’m not saying that every little app has to be this big, blown-out, enterprise application. I’m just saying that you should be careful when you cheat, because you don’t want that to come back to haunt you.

Many times you can take simple steps to make things easier to change. Take dependency injection, for example. It is really easy to set up an IoC container like StructureMap, it doesn’t overly complicate your code, and you don’t have to write tons of extra code to use it. But if you want to write tests for you code, dependency injection will make it a lot easier. You’re just putting code in better places.

Again, there are times to use dependency injection and there are times where it’s superfluous. There are times when unit testing is essential and times when you can get away with it (personally I always like writing tests if I can, that way I know my code works). But you need to be careful. Software is software, and many of the same development principles that apply to big apps still apply to small apps.


Kick It on DotNetKicks.com

Helping everyday developers succeed

Posted on January 22nd, 2009 in .NET, Design, Fluent NHibernate, LINQ, NHibernate, WCF by Jon Kruger

Software development is hard. You have to know how to use so many different tools and you have to try and keep up with it all.

Lately I’ve been hearing some griping about certain tools that people feel are trading good software design principles for ease of use. Many of these tools usually have some kind of drag-and-drop designer functionality that is designed to help you get things done faster. The griping comes from the fact that these tools can cause developers to make poor design decisions because the drag-and-drop tool led them in the wrong direction. I can’t say that I disagree with these complaints.

There are two sides of every coin, so let’s swing the pendulum the other way. Many open source libraries that I’ve seen take a different approach to design and the people that write them say that they’re not writing them for the novice user and that you will have to be familiar with advanced design patterns in order to use these tools. I think this is a good thing because software development is complicated and it’s OK to have make a library more complicated so that it fits in with good design patterns (like the need for an IoC container in FubuMVC).

Sometimes I wonder if we could do more to make these complicated tools easier to use. Take ORMs for example. Most people out there would agree that NHibernate is the most fully-functional ORM that we have. Yet I was on a project a couple years ago where developers floundered around trying to get their NHibernate mapping files to work (usually because of stupid stuff like typos, not making the .hbm.xml files Embedded Resources, not fully qualifying an assembly name, not making something virtual, etc.). Eventually we got better at it and we learned the tricks, but we wasted a ton of time trying to fix stupid mapping file issues.

For the next project I was on, we chose LINQ to SQL over NHibernate (this was in early 2008 when LINQ to SQL had just come out). I had an existing database with my tables in it, so I dragged them all into the LINQ to SQL designer and started writing business logic. It was amazing! It all just worked!

Now that led me into other pitfalls because now I had to map my objects 1:1 with my database tables, and crap from the database concerns cluttered up my model and caused a lot of grief. But even with that, we got work done much faster with LINQ to SQL than with NHibernate. Does this mean that LINQ to SQL is “better” than NHibernate? I wouldn’t say that, yet I was able to be more successful with LINQ to SQL. This is an important thing to note.

Open source tools like NHibernate are usually written by really smart people. Really smart people have no trouble figuring out complicated stuff. Sure, they may experience the same pain at first, but they pick it up quickly. All of the other really smart people that they talk to understand it too.

Not everyone is really really smart, unfortunately. I hear a lot of people harp on NHibernate and say it’s way too hard to use, that it’s not worth it, that there has to be a better way, etc. Most of these opinions come from a bad experience that they had with NHibernate.

I can’t discount these opinions that people may have. While these same people may agree that NHibernate is the most fully-featured ORM out there, for them it is not the ORM that will make them the most successful. I know a lot of people in this camp and they are not stupid people and they aren’t too lazy to learn NHibernate. It’s just that NHibernate did not lead them into the pit of success.

The fact is that most developers that are going to be using tools like NHibernate are your common, average, everyday developer — not bad developers by any stretch of the imagination, but they’re not as smart as the really smart people. I’m certainly not saying that we should sacrifice functionality and good design patterns to make things easier to use. I just think that more effort should be spent on making sure that average developers can figure out how to use something correctly, whether through documentation, good examples, or coming up with easier ways to do things. Really smart people don’t need these things to be successful with these tools, but the average developer will benefit immensely.

For me, this is what Fluent NHibernate did for NHibernate - it abstracted away a lot of what was difficult about NHibernate. Recently I’ve been able to use it on a project and it totally turned the tables. Now I get the power of NHibernate but I can use conventions to auto-wire my mappings, and the mappings are all in code instead of in XML. For me this is a huge deal. Now I get the power of NHibernate and I’m not stuck doing all of the crap that slowed me down before.

Another example of this is the reams and reams of documentation that the Microsoft patterns & practices team has written up for writing secure applications with WCF. WCF is very complex and powerful, but Microsoft did not leave us hanging and wrote up what to do in almost every scenario imaginable. They didn’t just give us a tool, they gave us what we needed to be successful with it.

We need more stuff like this.


Kick It on DotNetKicks.com