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