I’m building an application server that is heavily based on attributes, DI (indirectly via an IOC), and the command pattern.
Basically, you can tell it which “features” to start. It finds those features via attributes (by name), then starts all command processors associated to the feature (also defined via attributes). Each things announces the other things it needs, then those things are found and started.
When you pull an attribute off of a type, you are given an instance of a class. It’s a regular class for which you can use the default constructor, or a constructor that accepts primitive types.
In some cases in the app server, I want the attribute to represent an object that is populated by the DI container. How do you get the IOC (or some other factory) to construct an instance of an attributes?
As far as I know, you can’t. So, I’m using what I am calling an attribute surrogate.
The attribute surrogate is an attribute that refers to a class. The thing consuming the attribute extracts the type information from the attribute, then uses the IOC to construct the other type.
You see that in this case it has a NAME property that is a string. I started by using a TYPE, which works just as well, but in the case of the app server it’s using the string as everything else within it does. (For more generic purpose, change the NAME attribute to a TYPE).
15:/// <param name="name">The name of the service to register.</param>
16:public HostWcfServiceAttribute(string name)
17: : base(name)
Now, the app server sees the Command Provider Surrogate attribute and pulls off the name property. It uses the Type Cache (previously blogged about) to find the type by name. (The actual type has a NAME attribute on it which is used to identify and find it). Then, the Type is passed to the IOC which constructs an instance of that type. The IOC does all of the dependency injection, etc, just like it’s supposed to.
Here is the method that does all of that work. IObjectFactory is an abstraction on top of the IOC. As far as the code is concerned, it’s using a generic factory. The implementation of it is an unity container.
28: var surrogate = this.objectFactory.GetInstance<ICommandProviderSurrogate>(surrogateType);
29: surrogate.SourceFeature = this.feature;
30: surrogate.SourceAttribute = attribute;
32: var commands = this.getter.Invoke(surrogate);
33:if (commands == null)
For more generic use, have the attribute specify a type, then you can eliminate the TypeCache part of it.
This entry was posted on Monday, February 25th, 2013 at 2:46 am and is filed under Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.