Question

I recently are using Unity as IOC. Although I am not really using it as a dependency injector, I am using it as a factory.

Now, in my code I am using the following to register types:

container.RegisterType<IFooInterface, FooClass>(
            new[] { new InjectionProperty("SomeProperty", "SomeValue") });

Is there a way to use strong typing for the property injection?

Was it helpful?

Solution

You could do it with a fluent API.

public static class ContainerExtensions
{

    public static InjectionBuilder<TFrom, TTo> BuildInjections<TFrom, TTo>(this IUnityContainer container)
        where TTo : TFrom
    {
        return new InjectionBuilder<TFrom, TTo>(container);
    }

    public static MemberInfo GetMemberInfo(this Expression expression)
    {
        var lambda = (LambdaExpression)expression;

        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = (UnaryExpression)lambda.Body;
            memberExpression = (MemberExpression)unaryExpression.Operand;
        }
        else
            memberExpression = (MemberExpression)lambda.Body;

        return memberExpression.Member;
    }
}

// This class is the fluent API
public class InjectionBuilder<TFrom, TTo>
    where TTo : TFrom
{
    private readonly IList<InjectionMember> _injectionMembers = new List<InjectionMember>();
    private readonly IUnityContainer _container;
    public InjectionBuilder(IUnityContainer unityContainer)
    {
        _container = unityContainer;
    }

    public InjectionBuilder<TFrom, TTo> AddPropertyInjection<TType>(Expression<Func<TFrom, TType>> property,
                                                                    TType value)
    {
        var propName = property.GetMemberInfo().Name;
        _injectionMembers.Add(new InjectionProperty(propName, value));
        return this;
    }

    public IUnityContainer Register()
    {
        return _container.RegisterType<TFrom, TTo>(_injectionMembers.ToArray());
    }

}

Then use it like

        IUnityContainer container; // already Init
        container.BuildInjections<IFooInterface, FooClass>()
                 .AddPropertyInjection(f => f.SomeProperty, "SomeValue")
                 .Register();

You get type safety and you can keep adding in PropertyInjections until you call Register. You could also extend the class to register any other unity injection factories you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top