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?

有帮助吗?

解决方案

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top