Attribute Surrogate

February 25, 2013

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.

The surrogate attribute:

   1: namespace SomeGuySoftware.ApplicationServer.Contracts

   2: {

   3:     using System;

   4:     using SomeGuySoftware.Common;

   5:  

   6:     [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]

   7:     public class CommandProviderSurrogateAttribute : Attribute

   8:     {

   9:         public CommandProviderSurrogateAttribute(string name)

  10:         {

  11:             Validators.CheckRequiredArgument("name", name);

  12:             this.Name = name;

  13:         }

  14:  

  15:         public string Name { get; private set; }

  16:     }

  17: }

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).

I slap that attribute onto a class:

   1: namespace SomeGuySoftware.ApplicationServer.Contracts

   2: {

   3:     using System;

   4:  

   5:     /// <summary>

   6:     /// Put this on a feature to register a Wcf service.

   7:     /// </summary>

   8:     [CommandProviderSurrogate("WcfCommandProvider")]

   9:     [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]

  10:     [DependsOnFeature("WcfHostFeature")]

  11:     public class HostWcfServiceAttribute : WcfAttribute

  12:     {

  13:         /// <summary>

  14:         /// </summary>

  15:         /// <param name="name">The name of the service to register.</param>

  16:         public HostWcfServiceAttribute(string name)

  17:             : base(name)

  18:         {

  19:         }

  20:     }

  21: }

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.

   1: private void AddCommandsFromSurrogateAttribute(Attribute attribute)

   2: {

   3:     /*

   4:      The attribute may be a surrogate - this means that the class is decorated with the generic [CommandProviderSurrogate].

   5:      The better practice is to decorate a user-friendly attribute with [CommandProviderSurrogate].

   6:      The user-friendly attribute has properties that can be consumed by the surrogate command provider.

   7:      Example: [HostWcfServiceAttribute] is decorated by [CommandProviderSurrogate].

   8:      HostWcfServiceAttribute is a specific surrogate to start a service.*/

   9:  

  10:     // is the attribute a surrrogate?

  11:     var surrogateAttribute = attribute as CommandProviderSurrogateAttribute;

  12:     if (surrogateAttribute == null)

  13:     {

  14:         // does the attribute have a surrogate attribute?

  15:         surrogateAttribute = Attribute.GetCustomAttribute(attribute.GetType(), typeof(CommandProviderSurrogateAttribute)) as CommandProviderSurrogateAttribute;

  16:         if (surrogateAttribute == null)

  17:         {

  18:             return;

  19:         }

  20:     }

  21:  

  22:     var surrogateType = this.typeCache.GetType<ICommandProviderSurrogate>(surrogateAttribute.Name, false);

  23:     if (surrogateAttribute == null)

  24:     {

  25:         throw ApplicationServerExceptions.CommandProviderSurrogateIsntSurrogateType(attribute, this.feature);

  26:     }

  27:  

  28:     var surrogate = this.objectFactory.GetInstance<ICommandProviderSurrogate>(surrogateType);

  29:     surrogate.SourceFeature = this.feature;

  30:     surrogate.SourceAttribute = attribute;

  31:  

  32:     var commands = this.getter.Invoke(surrogate);

  33:     if (commands == null)

  34:     {

  35:         return;

  36:     }

  37:  

  38:     this.resultCommands.AddRange(commands);

  39: }

For more generic use, have the attribute specify a type, then you can eliminate the TypeCache part of it.


Type Cache

February 8, 2013

At work, over time we have introduced the need to find types in the app domain. This is to eliminate configuration in favor of convention and declaration.. Each of these needs came up independently, and each do it their own ways. That annoys me. it needs to be refactored so that the app domain is crawled only once, and all can share the results.

My latest personal project has the same needs. I created TypeCache to solve the problem.

You tell the cache what types to look for, and also what attributes to look for. Those types are loaded and stored, and the TypeCache is added to the unity container as a singleton. Anything that needs it simply accepts it as a dependency, and away it goes.

   1: public void Blah()

   2: {

   3:     var config =

   4:         new TypeCacheConfiguration()

   5:         .AddType<IServerCommand>(

   6:         .AddType<ICommandProcessor>()

   7:         .AddType<ICommandProvider>()

   8:         .AddType<ICommandProviderSurrogate>()

   9:         .AddType<IFeature>()

  10:         .AddAttributeType<NameAttribute>()

  11:         .AddAttributeType<WcfServiceAttribute>()

  12:         .AddAttributeType<WcfAttribute>();

  13:  

  14:     var cache = new TypeCache().Load(config);

  15:  

  16:     var names = cache.GetTypesThatHaveAttribute<NameAttribute>();

  17:     var wcf = cache.GetTypesThatHaveAttribute<WcfServiceAttribute>();

  18:     var wcfbase = cache.GetTypesThatHaveAttribute<WcfAttribute>();

  19:  

  20:     var services = cache.GetTypes<IFeature>();

  21:     var serviceByName = cache.GetType<IFeature>("name");

  22:     var typesWithWcfAttribute = cache.GetTypesThatHaveAttribute<WcfAttribute>();)

  23: }

I’m still working on the interface. I’m not a huge fan of the load method, but I didn’t want the constructor to initiate the crawl. So, while the details may change, the result is what I need. One thing that will have to change: inject the crawler rather than have it always do the full app domain. (Inspired by MEF catalogs).

The methods return types, usually by name (a custom attribute). Then, I use Unity to construct an instance of the type. It’s pretty sweet.

MEF

I have been somewhat familiar with MEF for a long time. Today I took the time to do my homework on it, wondering if I should have used it instead of inventing the type cache. So far, my answer is no, but I leave the issue open to debate. I want to use Unity for composition, not MEF. If anything, I just want MEF to find the types. I didn’t see anything that would reveal the type. (It can return a subclass of Lazy<T> which may contain the type information… don’t know without trying). For now, I’m going to stick to the TypeCache.


Model On-The-Fly

February 1, 2013

I’m trying to setup a simple way to define simple deployments. This is in support of my most recent project, and also something that can be used by Dev Dash.

Things can be organized like this:

  • A server is one or more server types
  • Each server type may have deployed to it one or more applications
  • Each application has one or more feature
  • Each feature may have one or more web services (and other things, too, but let’s limit it to web services for now)
  • Everything needs files (assemblies, etc)
  • You can group files into lists and add the lists to other artifacts rather than duplicating files

That’s a simple hierarchy. It gets more complicated, though, because you can add things outside of the hierarchy

  • An application has features, but it can also have web services and files assigned to it directly

Dandy. To complicate it more, I want to be able to remove things. For example: Feature A contains 3 web services. But, something above it may want to remove it. IE: Start Feature 3, but exclude one of the web services.

Thus, you end up with a default configuration that you can then add to or remove from.

My first instinct was to start creating some tables to do this, but then I reconsidered and decided to use Model First in EF and let it deal with the tables. Pretty modern of me, right?

image

It’s a whole bunch of entities with many to many relationships. Ugly. Furthermore, it didn’t work. The model shows the associations between the entities. Behind the scenes, those many-to-many relationships become join tables. If I created this myself in the database, then I would add a column to join tables that would allow me to indicate REMOVE. (IE: one entity inherits a property from another entity, but in this instance I don’t want it). You can’t do that in EF other than to build the join tables as entities, which would result in a nasty model.

Another issue is that I want it to be simple The sql to maintain this (lacking a suitable gui) would be ugly too.

Thus, I began a trial-an-error effort that lasted all week. I started to write something to handle this configuration issue specifically, but quickly realized I can do so more generically.

What I came up with is an on-the-fly model. In a single text file, I identify the object and properties I want, populate the objects, and apply rules. This gives me exactly what I need in a generic way, and I will be able to use it for other things.

That said, it remains immature. One thing that I will have to do (should I pursue this) is to define the model first, then populate it after. As-is, it does whatever you want. By defining the model first, rules and relationships can be defined then enforced.

server test1
	servertypes
		add servertype App Server
		remove [servertype App Server]/applications[application testapp]/webservices[webservice service1]
 
servertype App Server
	applications
		add application testapp
		add application testapp2
 
application testapp
	features
		add feature test1
	webservices
		add webservice service1
		add webservice service3
 
application testapp2
	features
		add feature test3
		add feature test4
	webservices
		add webservice service2
 
webservice service1
	files
		add string abc.dll
		add string def.dll
		add string ghi.dll
		add string readme.txt
 
webservice service2
	files
		add string a.txt
		add string b.txt
		add string c.txt
		addlist /[filelist somefiles]/files
 
webservice service3
webservice a
webservice b
feature test1
	webservices
		add webservice a
		add webservice b
feature test3
feature test4
 
filelist somefiles
	files
		add string list1.txt
		add string list2.txt
		add string list3.txt
		add string list4.txt
 
 
 
You can resolve any of the entities that you like, but since I am primarily interested in servers, let’s see what happens when we resolve Server1.
  • It is of type app server, so it gets 2 applications, which results in 3 features and 3 web services
  • It then removes one of the webservices that it doesn’t want.

Everything is driven by ENTITY TYPE and ENTITY NAME.

Entity Type is defined as the first piece of a non-indented line.

Entity Name is defined after the space following the entity type.

The first level of indent is the property names.

The second level of indent is the commands to populate the property.

Currently, everything is treated as an entity except for string. It is coded for specifically. Other primitives will follow as needed.

All properties are assumed to be collections of entities. That too will mature as needed. IE: set the value of individual properties.

Here’s one of the entity paths:

[servertype App Server]/applications[application testapp]/webservices[webservice service1]

That is on the ServerTypes property of one of the Server entities.

  • Finds an entity in the property’s value collection of type servertype and name App Server
  • Goes into the applications property
  • Finds an entity in the property’s value collection of type application and name test app
  • Goes into the webservices property
  • Fine an entity in the property’s value collection of type webservice and name service 1

Finally, it’s where it needs to be, and it removes it.

The ADDLIST command is similar.

addlist /[filelist somefiles]/files

Because it begins with the /, it resolves [file list somefiles] rather than look for it wihtin the property collection. It finds it, drills into the files property, and copies all of the values from the files property of the list to the property that contains the command.

There is one more major thing I want to do: have things automatically collapse into each other. For example: This resolves to server/servertype/applications/features/*. I don’t really care about server type. I want to be able to specify that all of the property of server type are rolled up into server, and we never see server type in the output. But, to do that properly, I must define the model ahead of time rather than on-the-fly. (Otherwise, the collapse rules would have to be defined for each instance of the entity… that’s no good.)

This is how I consume the file:

   1: var stream = new FileStream("ParseText2.txt", FileMode.Open);

   2: var structure = new Parser().GetStructure(stream);

   3: var resolved = structure.Resolve("server", "test1");

   4:  

  • Now, if I iterate the results and dump them to the console:
  • server test1
       servertypes
          servertype App Server – ENTITY
             applications – PROPERTY
                application testapp – ENTITY
                   features – PROPERTY
                      feature test1 – ENTITY
                         webservices – PROPERTY
                            webservice a – ENTITY
                            webservice b – ENTITY
                   webservices – PROPERTY
                      webservice service3 – ENTITY
                 application testapp2 – ENTITY
                    features – PROPERTY
                       feature test3 – ENTITY
                       feature test4 – ENTITY
                    webservices – PROPERTY
                       webservice service2 – ENTITY
                          files – PROPERTY
                             a.txt – 3 strings
                             b.txt
                             c.txt
                             list1.txt – 4 strings added at once from the list
                             list2.txt
                             list3.txt
                             listr.txt

    The next step is to conver that to concrete objects. I believe I will easily achieve that via Dynamic