Я пытаюсь вызвать метод 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 в код)