Tuesday, November 30, 2010

Taking IoC beyond DI with Autofac Part 1: Lifecycle Control

People who have to listen to me talk about programming know that I’m a big proponent of Inversion of Control (IoC) containers and what they can do to clean up your code. Most people get introduced to IoC containers via Dependency Injection (DI). DI is another great way to clean up your code. It’s hard to argue against it, really. It decouples your code in a big way. Not only does this make it more testable, but because it aids in separating concerns/responsibilities, this also makes it easier for you to track down bugs when they do show up. But people rightly point out that you don’t need an IoC container to use DI and get these benefits.

I’m usually both happy and sad to hear that argument. On the positive side, it means that people are acknowledging the benefits of DI, which is great. The more people are using DI, the less god classes full of spaghetti code there are out there for me to unearth in future maintenance efforts. Another reason I’m happy to hear that argument is because it means that people aren’t confusing the means for the end. DI is a good thing, for the reasons I established above, not because, as some people seem to think, IoC containers are good and DI is what IoC containers do.

That last sentence there leads into the reason that I’m sad to hear people dismiss IoC containers as being unnecessary for DI. The problem is, DI isn’t the only benefit of IoC containers. DI isn’t what IoC containers do. IoC containers, as their name would indicate, invert control. They take a number of concerns that have traditionally been assigned to the class under consideration, and extract them out to the context in which that class is used. That context may be the immediate consumers of the class, or it may be coordinating code, infrastructure, data access, or any number of other locations in the application. But the point is that the responsibilities are removed from the class itself and given to other classes whose business it is to know what should be created, when, with what initialization, and how it should be disposed of.

A good IoC container does more than just wire up constructor dependencies. It goes beyond that and lives up to the breadth of this definition of IoC. And that is why I laud and evangelize the glories of IoC containers.

Lets take a look at one particular container that I’ve come to know and love: Autofac. It’s an amazing framework that offers an answer to nearly everything that the principles of IoC ask of it. Autofac has features for lifecycle control, object ownership, and deterministic disposal. It has features for nested scoping, contextual dependency resolution, and varied construction mechanisms. These are all concerns that are a function not of the consumer of a dependency, but of the cloud of code and functionality that surrounds it, of the nature and design of your application as a composition. And Autofac gives you ways to deal with them on those terms.

Autofac boasts strong support for robust lifecycle control. In the project wiki you’ll find it laid out under the topic “Deterministic Disposal”, but it’s about creation as much as it’s about disposal. When you register a module with an Autofac container, you have the opportunity to specify a scope strategy. This strategy will determine whether a new instance is created upon the request, or whether an existing one is pulled from the container. Furthermore, it will also determine when references to the instance or instances are released and Dispose called on IDisposables. I’ll be doing some explaining, but if you want to do your own reading on the available strategies, you can do so here: http://code.google.com/p/autofac/wiki/InstanceScope

The two simple lifetime scopes that everyone tends to be conceptually familiar with are found n Autofac’s SingleInstance and InstancePerDependency scopes. The former is roughly equivalent to the function of a singleton pattern implementation, while the latter corresponds to a factory pattern implementation. Autofac goes well beyond this, however, and gives you two more scoping strategies that let you manage creation and disposal of your components in a more nuanced and more powerful way.

Both of the two more nuanced scope strategies depend on Autofac’s support for “nested containers”. A nested container is essentially a scoping mechanism, similar to a method or class definition, or a using block. Nested containers are useful for establishing the architectural layer boundaries of your application. For example, in a desktop application you may have many windows coming in and out of existence, all operating on the same domain objects, persisting them via the same handful of repository classes. These windows may be created in nested container contexts that are spun up as needed, and disposed when the windows are closed. Some objects will be created new each time this happens, while others are unique and shared across the entire UI. The nested container is what allows Autofac to make the appropriate distinction.

Imagine you are writing a file diff’ing application. You have to show two documents at once in side-by-side windows. They are the same thing, in terms of functionality and data, and so could just be two different instances of the same object.... But they will share some dependencies, and have references to their very own copies of certain others.

Lets pick out a few pieces of this puzzle and tie them to Autofac’s features. You will probably have a file access service that allows you to operate on the files that you have loaded. There’s no reason to have more than a single copy of this in the entire app, so it can effectively be a singleton. The way you would express this to Autofac is via the registry.

Given the class and interface definition:

You would register the component as a singleton like this:

The run-time behavior you would see based on this registration is that only one instance of the FileAccess component will ever be produced by the container. Subsequent requests will just return the one that’s already constructed.

The next layer on top of that is the UI. You decide that you may want to be able to have multiple comparison windows open at once, without having to run separate instances of the app. But each of those windows is still essentially a full instance of your apps interface. They’re not exactly singletons, but they should be unique within their separate stacks. Whatever sub-context they are in, there should be only one.

Given the class and interface definition:

You would register the component using the InstancePerMatchingLifetimeScope strategy, like this:

One weakness of Autofac for this use case is that in order to establish the proper resolution contexts, you have to refer directly to the container. In this case it’s probably okay, since you can be fairly certain you’ll only ever need a Left context and a Right context. So you can probably create the lifetime scopes up front, store them away somewhere, and explicitly resolve these objects from the separate contexts when needed. A sample setup for this can be seen below.


Then you’d need to make sure that the LeftContainer and RightContainer were used explicitly to resolve the left and right ComparisonWindow components.

This works for us in this situation. But it’s not at all difficult to imagine a scenario, maybe even in this same app, where the contexts aren’t predetermined and static. For example, you may want have a worker thread pool, where each thread has its own resolution context. In fact this is a situation addressed explicitly in the Autofac wiki. Even there, it seems to be accepted that an explicit container reference in the thread pool is necessary. It doesn’t seem like there’s a great solution to this challenge at this time, though I will surely be keeping an eye out for one. This is messy, concern-leaking infrastructure code that I would really prefer not to have to write.

There’s another scoping type that’s related to this one. In fact it’s use is a bit simpler. This is the InstancePerLifetimeScope strategy. Note the subtle lack of the “Matching” adjective in the name. What this indicates is that the context is implied rather than explicit. The behavior specified by this strategy is that at most one instance will be created within the resolution context where the resolution happens, at whatever level of nesting that happens to be. Functionally, this differs from InstancePerMatchingLifetimeScope in that it doesn’t search the context stack for one particular context in which to do the resolution.

This strategy can be effective when you have a set architecture with a trivial tree structure. Well-defined layering is crucial. All the leaf nodes of your context tree need to be at the same depth in order to be certain when a new instance will be created and when not. For example, a website where you have a base layer for the whole web app, and a leaf layer nested within for each individual web requests. In our diffing app, if we can be certain that we need no more deeply nested containers beyond our LeftContainer and our RightContainer, and all significant service resolution will happen at those layers, then we may have a use for this strategy for the dependencies of our Left and Right windows and controllers

The registration for this strategy is very similar to the others. Given a class and interface definition such as this:

The registration would look like this:

The final scoping strategy is InstancePerDependency. As noted before, the behavior is roughly equivalent to an implementation of a factory pattern. Every resolution request for a service registered as InstancePerDependency will result in the creation of a new instance. In our diffing app, we may find use for this strategy with something like an alert dialog. There’s no need to keep an alert around when it’s not being shown, and in fact it should almost certainly *not* carry any state from one alert to the next.

So given a class and interface such as this:

The registration would look like this:

That covers most all of Autofac’s lifecycle control functionality. There are four strategies available: SingleInstance which approximates Singleton, InstancePerDependency which approximates Factory, and the more subtle and, honestly, difficult to use, InstancePerLifetimeScope and InstancePerMatchingLifetimeScope which are heavily contextual. I really wish that these last two were more manageable and directable. If they were, I think that Autofac could claim to easily address most any lifecycle control need with very little overhead and requiring few concessions to the framework. This would be a very noble goal. But as it is, their behavior will tend to be circumstantial rather than controlled and intentional. And the only hope of improving that situation lies in taking great pains to organize your design to account for the container’s shortcomings and then go on to break the rule of not referencing the container.

Despite these shortcomings, I believe there are many benefits to be found in relying on Autofac for lifecycle control where it’s possible and not overly problematic. Certainly I’ve saved myself some headaches in doing so. And we haven’t even begun to explore the dependency relationship patterns that Autofac supports out of the box. We'll dive into to those next time!

Tuesday, November 23, 2010

A Noob's Scattered Thoughts on REST

Note: I hope you'll bear with me as I meander through my still very disorganized thoughts on the topic. This post is very much for myself, with the goal of distilling the information floating around in my head into something more concrete and which I can actually make use of...

I have a few projects on the horizon, both at work and on my own, which will involve web services in some form or another. I have to admit, I've never been much of a "web guy" before. My career to this point hasn't demanded that this change, but it looks like it's time for me to move off the desktop at least part-time. So I've dived into web services.

I develop for .NET at work. So while I may explore something else for my personal projects, for work I have to focus on .NET frameworks. Of course REST is all the rage these days, so it's obligatory that I research that. So I've read a number of blog posts describing what REST is about. My assessment of the REST is that it seems like a nice idiomatic design philosophy for a web service that deals primarily with persistent data entities and operations over them.

It seems clear to me though that there must be problems which might be addressed via a web service which aren't necessarily natural to model using REST. Of course the fallback, if one were to decide that the barrier is too great, would be to use some sort of RPC style. RPC comes natural to us developers, of course, because it's essentially just a web-enabled version of the idioms we use ubiquitously in code.

My own feelings about RPC as compared to REST are less critical than many. I understand the philosophical imperative to maintain the webbishness of services operating over the web. However, I also hold very strong to the opinion that solutions should be created using metaphors that lend themselves naturally to the problem space. REST, as defended by many, seems to me to be less about the problem space than it is about the mechanism the solution is built on.

However, if REST can be said to consist of two pillars, resource-orientation and mapping operations to the HTTP verbs, then it seems the later is really the part that seems limiting. After all, a resource is not so different from the "objects" that permeate our code as programmers. But imagine if, in your object-oriented design, you were allowed only 4 methods per object, and each of them had to fit one of four very specific patterns. That feels arbitrarily limiting, doesn't it? It does for me.

Now, having said that, I do see value in keeping things simple. The web is already a high level abstraction. And building convoluted metaphors on top of it that don't map easily to the mechanisms that underly it can cause a lot of unnecessary headaches. I also believe that it may not be unfair to compare RPC-heavy designs to the old style of procedural programming. That is, that they have all the nasty kinds of coupling and inertia, and few of the good kinds. Especially when the data entities involved are mutable.

That last point hits home hard for me, though. And I think it will end up strongly informing how my designs play out. The reason for this has largely to do with how my overall coding style has evolved over the past couple of years. I've found lately that, with the exception of DTOs and the primary domain objects in my solutions, a great many of the objects I work with tend to be immutable. And the algorithmic bits that operate on them tend to come in nuggets of functionality that are highly composable. This strikes me as being fairly compatible with REST's resource-oriented design.

Another factor I have to consider is the frameworks that are available to me. Comparing what I can find on the web about WCF and ASP.NET, the primary non-REST web service frameworks, and OpenRasta.... I have to say that the code and configuration of OpenRasta solutions seems to be much simpler, more elegant, and clearer of intent. This appeals to me greatly. It seems like it would be much easier not only to spin up something from scratch into a working solution, but also to evolve smoothly from my first fumbling attempts through to a final product that still has clarity of structure and intent. If I've learned anything in my career so far, it's the importance of that.

So my initial forays, at least, will likely be based in OpenRasta. If it turns out that OpenRasta can't give me what I need, or that there's too much friction, I'll look for help of course. But I also won't be afraid to try to weave some RPC into my design if it's called for.

Monday, November 15, 2010

Clean Injection of Individual Settings Values

The Setup

Today I again encountered a challenge that I have dealt with numerous times while working on the product I develop for my employer. It's not insurmountable an insurmountable challenge. Honestly, it's not even all that challenging. But it has been an irritant to me in the past because all the solutions that I have come up with felt unsatisfactory in some way.

That challenge is the injection of simple settings values into the classes that need to refer to them. By simple I mean single-value settings embodied by an integer, a string, or a floating-point, for example. This seems like a simple problem. And honestly, I thought this was going to be a short and sweet post, until I realized that there is value in delineating all the dead ends I've followed on the road to my current favored solution. As you'll see, I've put a fair amount of thought and analysis into it.

Being a hip programmer, I use an IoC container to constructor-inject all my complex dependencies. And my IoC container of choice, Autofac, is only too happy to auto-wire these so I don't have to worry about them. But mixed in among these are the simple settings values that guide the functionality of certain classes. A component/service model doesn't really apply to these values. No one string value is implementing the "string" service. The values can't be easily auto-wired because unlike the complex classes there is certain to be more than one important value floating around for the primitive type in question.

Our app processes image. Large files, and large volume. And worse, the working sets are very large, so we can't handle things piecemeal. We have a serious need in a few different places for disk caching of "active" entities that are still very much in flux. Having multiple caching points necessarily means that there are several parameters that may need to be tweaked to keep things optimized. For each cache we want to be able to set the disk location for the cache and the in-memory entity limit, just to start.

Taking a simple case with two cache points, we have two string settings and two integer settings. So already we are in a position where in order to inject the values, we'll need to do some sort of "switching". Some run-time decision of which string and which integer go where.

Pitfalls and Red Herrings

As I noted in my opening, I have solved this in several ways in the past. One is to hook into the IoC via Autofac's "OnPreparing" event, where I can supply values for particular constructor parameters. This is nice, because it means I can avoid setter injection. But it complicates the IoC bootstrapper by adding exceptions and special handling for particular classes. Just as undesirable, it couples the IoC bootstrapper directly to the settings mechanism.

What about setter injection? Autofac provides a post-construction OnActivated event that is perfect for setter injection, but this is subject to the exact same disadvantages as the pre-construction event. We could leave the setters alone and let some other object fill them in, but that leaves us with a couple different problems. First, there's just as much coupling, it's just outside the IoC, which may or may not be a marginal improvement depending on how it's implemented. If you end up with some class that must be aware of both the app settings mechanism and the class(es) that receive those settings then this is really not much of an improvement.

But beyond that, refraining from providing the values until after the components are obtained is undesirable for yet a few more reasons. First and foremost, it means that your services will exist in a state of incomplete initialization. The risk of getting hold of an incompletely initialized service makes calling code more brittle. And protecting against the possibility makes it more complex. Furthermore, setter injection for these particular types of values is undesirable because it implies they are variants. The truth is that the last thing you want is for some errant code to change the cache location on disk after a bunch of files have been stored there. And putting in protection against such post-initialization changes is pathologically unintuitive: it subverts the very nature and purpose of a setter.

So we've established that these direct injection routes are problematic in a number of ways. Let's move on to indirect injection. What does that mean? Basically it means putting a provider object in the middle. Our classes can take a dependency on the setting provider, which can wrap the settings mechanism itself, or act as a facade for a bundle of different mechanisms.

The option that at first appears simplest is to have a single settings provider object through which all the app's settings can be accessed. The classes can all depend on this object, which the IoC can provide with a singleton lifecycle if we desire, for maximum consistency. But now what we have essentially done is created a service locator for settings. This is another thing that's good to avoid for two reasons. For one, it creates a huge common coupling point, and for two, it violates "tell, don't ask". Why should my dependent class have to depend on a generic interface and worry about asking for the appropriate thing, when all it cares about is just that one thing?

This is especially dangerous if the app-side interface to your settings keeps them grouped just as they are in the user-side (i.e. the config file), as the build in .NET config mechanism is wont to do. The needs of the user for the purpose of managing settings individually or en masse are vastly different than the needs of the application whose behavior is driven by those settings. While a user likely thinks the most intuitive arrangement is for all the 15 of the paths to be bundled together, it's highly unlikely that any particular class in the application is going to care about more than one or two individual paths. And if the class doesn't need them, then they shouldn't be offered to it.

A Light in the Dark

So where do we go from here? If you can believe it after all this meandering and rambling, we're very close. From here we take a little tip from the DDD community: eschew primitives. If you think back to the beginning, the whole problem centers on the fact that primitives are just too darn generic. The type doesn't mean something specific enough for it to be an indicator of what exactly the dependency is. How do we fix this? Encapsulate the individual setting in a type specific to that need. Given that the explicit purpose of these classes will be to provide particular settings to the classes that need them, it is appropriate for these to couple to the configuration mechanism, whatever that may be, and more importantly, encapsulate it in useful bite-size chunks. And because the providers will themselves be injected where needed, the coupling is one-way, one level, down the layer hierarchy, which is arguably the best kind of coupling.

Show Me The Code

Enough talking. Now that I've set the stage, here's some code to furnish and light it.

First, the setting providers. As you can see, they tend to be nice and short and sweet.

Next, the caches that depend on them. Note how the setting providers are used in the constructors.

Finally, I'll show just how easy it can be to wire these up. If you bundle all your setting providers in one namespace, you can even safely auto-register them all in one fell swoop!

Objections?

There are a few things that I can anticipate people would object to. One is the potential for proliferation of tiny classes. I don't see this as a bad thing at all. I think it's fairly well established that small classes, and methods, with laser-focused responsibilities are far easier to maintain, evolve, and comprehend. I can say from personal experience that I am utterly convinced of this. And if anecdote isn't good enough for you, I'll add an appeal to authority to it =) Go read up on what the most respected programmers out there today are saying, and you'll see them express the same sentiment, and justify it very well.

Another thing I expect people to object to is that when taken as a whole, this pile of small classes looks like a bit of a heavy solution. And it is heavy in this context, where none of the actual app code is surrounding it. But nestle it inside a 50K line desktop app with hundreds of classes and it will start to look a lot better. For one, those classes and their namespace create sort of a bubble. It's a codespace that has boundaries and purpose. You know what's inside it, and you know what's not. It's a goal-oriented mental anchor to latch onto while you code, and that's a darn useful thing.