Unity.BuildUp не может устранить неоднозначность - PullRequest
1 голос
/ 03 ноября 2010

У меня есть класс с двумя конструкторами, оба конструктора имеют один параметр.Из-за ограничений, которые не стоит объяснять, я не могу изменить конструкторы или использовать класс-потомок.

Я не могу использовать Unity для создания экземпляров этого класса, потому что Unity видит 2 конструктора с одинаковым количеством параметров и жалуется, что онне знает, что использовать, что достаточно справедливо.Поэтому вместо этого я сам создаю экземпляр и затем пытаюсь использовать UnityContainer.BuildUp ()

var result = constructorInfo.Invoke(new object[] { content });
UnitContainer.BuildUp(result);

Приведенный выше код не устанавливает ни одно из моих свойств [Dependency], и при этом я не вызываю [InjectionMethod], если я используючто вместо этого.

var result = constructorInfo.Invoke(new object[] { content });
UnitContainer.BuildUp(typeOfObject, result);

Это вызывает еще одно исключение в отношении неоднозначных конструкторов, хотя я не прошу его создать экземпляр.

У кого-нибудь есть идеи?

Вот пример приложения

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using System.Reflection;

namespace ConsoleApplication7
{
    public interface IConstructorType1 { }
    public interface IConstructorType2 { }
    public interface INeedThisDependency { }
    public class NeedThisDependency : INeedThisDependency { }

    public class MyDomainObject
    {
        public MyDomainObject(IConstructorType1 constructorType1) { }
        public MyDomainObject(IConstructorType2 constructorType2) { }

        [Dependency]
        public INeedThisDependency Needed { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer unityContainer = new UnityContainer();
            unityContainer.RegisterType<INeedThisDependency, NeedThisDependency>();
            //Try with type 1 constructor
            ConstructorInfo constructorInfo1 = typeof(MyDomainObject).GetConstructor(new Type[] { typeof(IConstructorType1) });
            MyDomainObject instance1 = CreateTheInstance(unityContainer, typeof(MyDomainObject), constructorInfo1, null);
            //Try with type 2 constructor
            ConstructorInfo constructorInfo2 = typeof(MyDomainObject).GetConstructor(new Type[] { typeof(IConstructorType2) });
            MyDomainObject instance2 = CreateTheInstance(unityContainer, typeof(MyDomainObject), constructorInfo2, null);
        }

        //This is the only point I have any influence over what happens
        //So this is the only place I get to change the code.
        static MyDomainObject CreateTheInstance(IUnityContainer unityContainer, Type type, ConstructorInfo constructorInfo, object parameters)
        {
            var result = (MyDomainObject)constructorInfo.Invoke(new object[] { parameters });
            //This will throw an ambiguous constructor exception,
            //even though I am not asking it to construct anything
            unityContainer.BuildUp(type, result);
            //This will not build up dependencies
            unityContainer.BuildUp(result); 
            if (result.Needed == null)
                throw new NullReferenceException("Needed");
            return result;
        }
    }
}

Ответы [ 2 ]

1 голос
/ 05 ноября 2010

Это ошибка в BuildUp, к сожалению.

0 голосов
/ 12 ноября 2010

Вместо вызова BuildUp вызовите этот помощник CallInjectionMethod.

public static class UnityContainerHelper
{
    public static void CallInjectionMethod(this IUnityContainer unityContainer, object instance, params ResolverOverride[] overrides)
    {
        if (instance == null)
            throw new ArgumentNullException("Instance");

        var injectionMethodInfo = instance.GetType().GetMethods().Where(x => x.GetCustomAttributes(typeof(InjectionMethodAttribute), true).Any()).SingleOrDefault();
        if (injectionMethodInfo == null)
            return;
        var parameters = injectionMethodInfo.GetParameters();
        if (parameters.Length == 0)
            return;

        var dependencies = new object[parameters.Length];
        int index = 0;
        foreach (Type parameterType in parameters.Select(x => x.ParameterType))
        {
            dependencies[index] = unityContainer.Resolve(parameterType, overrides);
            index++;
        }
        injectionMethodInfo.Invoke(instance, dependencies);
    }
}
...