Question

The two common mechanisms for creating dependency injection bindings, such as through an IOC container, is from an XML configuration or a block of imperative code. In these cases, the key value pair is explicit (i.e. key = requested type, value = returned type).

Still, there is a third "heuristic" approach where an application/IOC container is given only [IMyClass] keys and the container then reflects over a set of application assembly dependencies to find all name-matched concrete classes [MyClass]. Said differently, the "return type" values are discovered rather than declared.

What I'd like to know is twofold:

  1. Which IOC containers (or other late-binding tools) permit the heuristic approach? Does this approach have a more common name?
  2. Are there other binding techniques, besides the three I've listed, which are used in practice?
Was it helpful?

Solution

This is called Convention-based Configuration or Auto-registration and is supported by these .NET DI Containers:

The most common configuration mechanisms used for DI Containers are

  • XML
  • Code as Configuration
  • Convention-based Configuration

A fourth, but uncommon, approach is to use attributes. The Managed Extensibility Framework is the most prominent example of this approach, which is more common in Java.

OTHER TIPS

What you call a "heuristic" approach is what I call conventions. Most IoC containers allow you to override how they resolve bindings, which means you can introduce any convention you want. There are no such default conventions that I know of. Rather, most containers do nothing as their default; it is your job to tell them how to resolve types, either through a configuration file or through code.

An example of a custom convention I find is rather common which saves you a lot of declarations: If the requested type is an interface type starting with "I" and ending with "Service" then attempt to create and resolve a type with the same name apart from the "I". This will resolve names like IFooService to FooService automagically. In addition, you can introduce logic to decide on different services in different contexts rather easily, and you can handle service instance lifetimes in a common place.

Since you can override how most IoC containers bind, you can introduce other behaviors as well. Generally, however, there are really two options:

  1. Configure at run-time (through configuration files such as XML files)
  2. Configure at compile-time (either through a declarative DSL-like API or through custom conventions or another form of custom logic)

I did usually what you describe as a custom step in the congiguration. AFAIK there is no container providing out-of the box such a strategy ( and in my opinion is not a container part, but a configuratin stuff that should be external from the container responsibility ).

Since I've used StructureMap quite a bit I'd know how to do such a thing with that container: It would basically be a Custom Registration Convention (From Initialization or a Registry, go into the Scan-lambda block and find the "Convention" method).

It allows you to look at the reflected types and then insert them into the container configuration as you see fit. It should allow what you are trying to do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top