Category Archives: 15111

Plain Old Objects and MEF

After my MEF presentation at the Hampton Roads .NET User Group someone asked me about creating objects like customers and invoices via MEF. I gave an overly quick answer to a really good question.


A lot of the IoC history involves using dependency injection for services. This is great partly because it’s a framework to isolate plain old objects from services, and services from each other. Like many of the techniques we’ve adopted in the agile timeframe, it’s not just what the technique does for us, but what the technique does to us. That’s the quick answer I gave.


But, we can go further to fully composed systems. Fully composed systems have offered mind boggling benefits in some places they’ve been tried, and they haven’t been tried in very many places yet. This is why I have such a high fascination with NetKernel and the work people like Randy Kahle (@RandyKahle) and Brian Sletten (@bsletten) are doing. And that work is similar to work Juval Lowy and I have talked about for a number of years.


However, fully composed systems with MEF, and I assume other DI tools (although I’ll be happy to be proven wrong) are hard. Without the infrastructure of something like NetKernel there’s a fair amount of work to do, and without the caching benefits of NetKernel it’s going to be tough to justify. It’s hard because everything needs an interface. Everything. And even if you generate the interfaces and plain objects, the level of infrastructure ceremony gets very unwieldy.. At least that’s my experience from using MEF to wrap everything (yes, everything) in interfaces, in order to create a fully composed MEF 1.0 system.


We could go a slightly different direction. Put everything into the container, but place plain old objects in the container as their own type, rather than via an interface. Plain old objects in this sense are objects that we can’t imagine a scenario where they’ll be reused and they have a unique, and generally multi-valued interface. A customer or invoice POCO would be examples.


Placing these objects into the container offers the immediate benefit of guaranteeing their usage is isolated We take advantage of what DI does to us, not just for us..


And if we use inference in MEF 2.0 (.NET 4.5), and probably configuration techniques with other IoC containers, we can stick another object in if we have a later reason to do it.


But here’s where strong typing bites us. Any new class that ever replaces that plain old object (the customer or invoice) has to be assignable to that class. That means it has to be that class or a class that derives from it. I’m still hanging on to the strong typing life boat because I still feel that without it I’m in a North Atlantic storm. For big systems, I think that’s still true, and while I put a lot of thought into making big systems into smaller systems, non-typed based DI is still a jump into icy water for me.


With the plain object in the container under its own type, if I get blindsided with a requirement that just doesn’t fit I can manage, I just have to write a wrapper for the non-derived object and the wrapper has to derive from the expected type. Ugly, but workable.


What I want to do is experiment with strongly typed systems with generated interfaces. I’ve already done this with traditional generation, and I want a solution that is cleaner than that. I don’t have the syntax worked out, but imagine that we never create the interface for our plain old object, we just tell the system to do it. The container uses the interface, all using objects request the object by its interface, and we humans can ignore it.


Until the day the plain old object needs attention. On that day, we make the interface explicit and do whatever we need to do.


But with the versions of .NET we have today, we can’t build this.

About a Dozen Things

It’s very easy to believe that our code does a lot of different things – we live in a world of incredible complexity with well over 10,000 classes and 100,000 members in the .NET framework (1). We write code of great complexity – sometimes it’s amazing that it even works.

Take a minute to stand back from your code and consider what it actually does. I have the privilege of being part of the Northern Colorado Architects and we asked ourselves this question last spring. I’ve mentioned that we found about a dozen in several talks, and was asked to share the list. I’d like you to challenge this list if you think your code does anything else. Well, that and because I think I am forgetting at least one:

- Persistence

- Validation

- Authorization

- Localization

- Display/Edit

- Report

- Log/audit

- Test

- Exception avoidance and recovery

- Process

- Calculate

- Workflow (*)

The complexity of our world comes from the thousands of ways we can do each of these things and the billions of combinations. The complexity of a particular software application comes from tossing all of these concerns together along with a top- dressing of entropy and stirring vigorously.

The first three items on the list are pretty straight-forward. There is similarity between validation and authorization because they are both guards, but one focuses on who and the other on what, and we tend to use different techniques.

Localization may eventually fold into Display/Edit but today code on that front is rather different. Display/edit and reporting are also very similar. They differ because reporting is complex read-only analysis which might not be done over current data and may or may not ever appear on paper.

Three of the items on that list we do for internal purposes: logging/ auditing, testing, and exception management. Assertions and code contracts are part of exception management and what I mean by exception avoidance. Something is wrong and we’re responding to that, rather than crashing our systems – but it’s still a response to something being wrong. Logging and auditing covers all system health reporting and hopefully testing is a straightforward concept – even if it’s not straightforward in practice.

You might consider it cheating to have two buckets as big as “process” and “calculate.” Certainly they are critical and complex. But from a concerns point of view, it doesn’t really matter what you are doing – you’re doing it. I make a distinction between a process that changes the state of the universe (often by altering a database or an external system) and calculation which supplies information without altering the state of the universe.

Only three things (other than workflow) on this list should alter the state of the universe – persistence, logging, and process.

Workflow falls into a very special category. I mean a specific kind of workflow – the interaction between the application and the non-software business world it lives in. I don’t mean using workflow or business integration tools to do processing. I’m not actually sure workflow should be on the list, because in practice, it merely uses the other eleven kinds of code. At the end of my contemplation, I include it because I’d rather not spend time arguing about whether it should be there. I do believe that this sense of workflow is one of the most important perspectives we can have when we step back from our code and think as analysts. It’s a perspective that includes user stories as a subset.

There’s a lot of grey area where the things our code does overlaps. Is there any code in your space that does not fall into one of these buckets?

It’s a profound view. Everything is a cross cutting concern.

(1) Brad Abrams, Number of Types in the .NET Framework, http://blogs.msdn.com/b/brada/archive/2008/03/17/number-of-types-in-the-net-framework.aspx