Non-magic property injection in Unity[source]

xml
<glacius:metadata>
    <title>Non-magic property injection in Unity</title>
    <description>description</description>
    <category>C#</category>
    <category>Programming</category>
    <category>Legacy blog posts</category>
</glacius:metadata>
<glacius:macro name="legacy blargh banner">
    <properties>
        <originalUrl>https://tmont.com/blargh/2010/12/non-magic-property-injection-in-unity</originalUrl>
        <originalDate>2010-12-04T00:13:52.000Z</originalDate>
    </properties>
</glacius:macro>
<p>
  <a href="http://unitycontainer.org/">Unity</a> provides a way to perform injection on 
  properties, meaning that when an object is resolved through its DI container, it will 
  inject values for pre-defined properties. For example:
</p>
<glacius:code lang="csharp"><![CDATA[public class Foo {
  public string Bar { get; set; }
}
// somewhere else...
container.RegisterType<Foo>(new InjectionProperty("Bar", "oh hai!"));
var foo = container.Resolve<Foo>();
Console.WriteLine(foo.Bar); // "oh hai!"
]]></glacius:code>
<p>
  Pretty nifty, but it still reeks of .NET 2.0 non-lambda lameness. This sucks because you 
  can't do all the cool stuff you're accustomed to, like type-safety, refactoring and static 
  analysis.
</p>
<p>
  So I fixed that. Unfortunately, Microsoft made the <code>InjectionProperty</code> class 
  impressively difficult to extend, so we use the composite pattern to achieve greatness.
</p>
<glacius:code lang="csharp"><![CDATA[public class NonMagicInjectionProperty<T> : NonMagicInjectionProperty<T, object> {
	public NonMagicInjectionProperty(Expression<Func<T, object>> propertyAccessor) : base(propertyAccessor) { }
	public NonMagicInjectionProperty(Expression<Func<T, object>> propertyAccessor, object propertyValue) : base(propertyAccessor, propertyValue) { }
}
public class NonMagicInjectionProperty<T, TReturn> : InjectionMember {
	private const string ErrorMessage = "Expected lambda expression like: foo => foo.Bar, where Bar is the name of the property to be injected";
	private readonly InjectionProperty injectionProperty;
	public NonMagicInjectionProperty(Expression<Func<T, TReturn>> propertyAccessor) {
		injectionProperty = new InjectionProperty(GetPropertyNameFromExpression(propertyAccessor));
	}
	public NonMagicInjectionProperty(Expression<Func<T, TReturn>> propertyAccessor, TReturn propertyValue) {
		injectionProperty = new InjectionProperty(GetPropertyNameFromExpression(propertyAccessor), propertyValue);
	}
	private static string GetPropertyNameFromExpression(Expression<Func<T, TReturn>> expression) {
		var parameterName = expression.Parameters[0].Name;
		var memberExpression = expression.Body as MemberExpression;
		if (memberExpression == null) {
			throw new ArgumentException(ErrorMessage);
		}
		var leftSide = memberExpression.Expression as ParameterExpression;
		if (leftSide == null || leftSide.Name != parameterName) {
			throw new ArgumentException(ErrorMessage);
		}
		return memberExpression.Member.Name;
	}
	public override void AddPolicies(Type serviceType, Type implementationType, string name, IPolicyList policies) {
		injectionProperty.AddPolicies(serviceType, implementationType, name, policies);
	}
}]]></glacius:code>
<p>Now you can do stuff like this:</p>
<glacius:code lang="csharp"><![CDATA[public class Foo {
  public string Bar { get; set; }
}
// somewhere else...
container.RegisterType<Foo>(new NonMagicInjectionProperty<Foo>(foo => foo.Bar, "oh hai!"));
// or for more type safety (but not super necessary, in my opinion)
container.RegisterType<Foo>(new NonMagicInjectionProperty<Foo, string>(foo => foo.Bar, "oh hai!"));
var foo = container.Resolve<Foo>();
Console.WriteLine(foo.Bar); // "oh hai!"]]></glacius:code>
<p>It's a little more verbose, but much more awesome.</p>