Вызов метода через отражение с универсальными шаблонами и переопределениями

Я пытаюсь вызвать метод RegisterType в контейнере Unity. RegisterType имеет в общей сложности 16 переопределений (некоторые из них являются параметрами, а некоторые - типами).

Я пытаюсь выполнить эквивалент:

Container.RegisterType<IMyDataProvider, MockData.MockProvider>("MockData", new ContainerControlledLifetimeManager())

Использование GetMethod () было полным провалом, поэтому я сделал это ужасно вещь:

     MethodInfo registerTypeGeneric = Container.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).
        Where(p => p.ToString() == "Microsoft.Practices.Unity.IUnityContainer RegisterType[TFrom,TTo](System.String, Microsoft.Practices.Unity.LifetimeManager, Microsoft.Practices.Unity.InjectionMember[])").FirstOrDefault();
     MethodInfo registerTypeSpecific = registerTypeGeneric.MakeGenericMethod( new Type[] { typeof(IMyDataProvider), Assembly.LoadFrom("MockData.dll").GetType("MockData.MockProvider") });
     registerTypeSpecific.Invoke(Container, new object[] { "MockData", new ContainerControlledLifetimeManager() });

И это прекрасно работает, вплоть до Invoke, который жалуется, потому что у меня нет параметров InjectionMember (они необязательны, и мне не нужно их давать). Итак, согласно документации, я должен использовать Type.InvokeMember () для вызова метода с необязательными параметрами.

Итак, я сделал следующее:

     Binder binder = new BootstrapperBinder();
     Container.GetType().InvokeMember("RegisterType",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.OptionalParamBinding | BindingFlags.InvokeMethod,
        binder,
        Container,
        new object[] { "MockData", new ContainerControlledLifetimeManager() });

Мой класс BoostrapperBinder делает это:

  public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] names, out object state)
  {
     Type mockProvider = Assembly.LoadFrom("MockData.dll").GetType("MockData.MockProvider");
     state = new object();
     MethodInfo mi = Container.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).
        Where(p => p.ToString() == "Microsoft.Practices.Unity.IUnityContainer RegisterType[TFrom,TTo](System.String, Microsoft.Practices.Unity.LifetimeManager, Microsoft.Practices.Unity.InjectionMember[])").FirstOrDefault();
     return mi.MakeGenericMethod(new Type[] { typeof(ICarrierApprovalDataChangeAccessorEndPoint), mockProvider });
  }

Да, это уродливо, но Я просто использую его в этом случае, так что он выполняет свою работу.

Проблема в том, что он все еще жалуется на отсутствие третьего параметра. Я тоже не могу передать null или Missing.Value, или он хрипит. Я пробовал с BindingFlags.OptionalParamBinding и без него. Я в тупике.

(Отредактировано, чтобы поместить пример Container.RegisterType в код)

6
задан Pete 13 June 2011 в 17:26
поделиться