Distributed configuration solution?
Christopher Wright
dhasenan at gmail.com
Wed Jan 9 19:23:40 PST 2008
Hi all,
I have a tiny, 90% complete dependency injection framework. As it
stands, it's head and shoulders above Microsoft's CAB framework (though
that's not hard). It avoids any order requirements in configuration,
which is the main advantage, and it even handles literals (strings and
other builtin types), special cases (injecting one thing while building
one type and a different when building a different type), arrays, and
associative arrays.
There's one glaring problem. Configuration. How to associate an
implementation with an interface or abstract class.
Currently, you can do this manually:
builder.bind!(IInterface, ClassImplementing);
This is ugly.
You put all the configuration in one place -- which is, I guess, a good
thing. But you keep the configuration for a given class/interface pair
far from the class and far from the interface. That is a bad thing. It's
a noticeable source of bloat. I don't want one of these giant 1000-line
module files like I've seen with CAB.
I want some means of registering implementations closer to the
implementations. But my code knows nothing about the implementations
unless it's told. It only has access to the interface.
1. My first idea was to fake C# attributes / Java annotations using
templated interfaces:
interface ImplementedBy(T) {}
interface UserInterface : ImplementedBy!(Implementation) {
//...
}
Then my code goes:
static if (is (TToBuild : ImplementedBy!(U), U)) {
return build!(U);
}
That's supposed to work, but it doesn't.
2. My next thought was a static constructor:
class Implementation : UserInterface {
static this () {
builder.bind!(UserInterface, typeof(this));
}
}
This is ugly.
3. Then I thought, combine the two:
abstract class Implements(T) {
static this () {
builder.bind!(UserInterface, ???? FAIL);
}
}
If I solved the template problem:
class Implementation : BaseImplementation, UserInterface {}
4. This leaves a mixin, which is only slightly ugly:
template Implements(T) {
// typeof(this) works here
return `static this () { builder.bind!(` ~ T.stringof ~ `,
typeof(this); }`;
}
class Implementation {
mixin(Implements!(UserInterface));
}
This seems to be best, but does anyone have a better suggestion?
I just hate that D forces these mixins plus static services rather than
having a decent way to provide metadata.
More information about the Digitalmars-d-learn
mailing list