Fork me on GitHub

Using Attributes for Configuration


The Lamar team believe that forcing users to spray .Net attributes all over their own code is in clear violation of our philosophy of minimal intrusion into user code. In other words, we don't want to be MEF.

That being said, there are plenty of times when simple attribute usage is effective for one-off deviations from your normal registration conventions or cause less harm than having to constantly change a centralized ServerRegistry or just seem more clear and understandable to users than a convention. For those usages, Lamar 4.0 has introduced a new base class that can be extended and used to explicitly customize your Lamar configuration:


public abstract class LamarAttribute : Attribute
{
    public virtual void Alter(IConfiguredInstance instance)
    {
    }

    public virtual void Alter(Instance instance)
    {
        
    }
}

There's a couple thing to note, here about this new attibute:

  • Lamar internals are looking for any attribute of the base class. Attributes that affect types are read and applied early, while attributes decorating properties or constructor parameters are only read and applied during the creation of Build Plans.
  • Unlike many other frameworks, the attributes in Lamar are not executed at build time. Instead, Lamar uses attributes one time to determine the build plan.

Attribute Targeting Plugin Type or Concrete Type

Take the new [Singleton] attribute shown below:


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class SingletonAttribute : LamarAttribute
{
    // This method will affect single registrations
    public override void Alter(IConfiguredInstance instance)
    {
        instance.Lifetime = ServiceLifetime.Singleton;
    }
}

This new attribute can be used on either the plugin type (typically an interface) or on a concrete type to make an individual type registration be a singleton. You can see the usage on some types below:


[Singleton]
public class SingleWidget : IWidget
{
    public void DoSomething()
    {
        throw new System.NotImplementedException();
    }
}

Built In Attributes

Lamar supplies a handful of built in attributes for customizing configuration:

  • [ValidationMethod] - Allows you to expose Environment Tests in your Lamar registrations
  • [DefaultConstructor] - Declare which constructor function should be used by Lamar. See Constructor Selection for more information
  • [Scoped] and [Singleton] - These attributes, just add another mechanism for lifecycle configuration
  • [InstanceNamed("name")] to override the instance name of a registered concrete class