I am trying to call the RegisterType method in a Unity container. RegisterType has a total of 16 overrides (some of them are parameters, some of which are types).
I am trying to execute the equivalent:
Container.RegisterType<IMyDataProvider, MockData.MockProvider>("MockData", new ContainerControlledLifetimeManager())
Using GetMethod () was a complete failure, so I ended up doing this ugly thing:
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() });
And it works fine, right down to Invoke, which complains because I don't have InjectionMember parameters (they are optional and I have nothing to give). Therefore, according to the documentation, I have to use Type.InvokeMember () to call a method with optional parameters.
So, I did this:
Binder binder = new BootstrapperBinder(); Container.GetType().InvokeMember("RegisterType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.OptionalParamBinding | BindingFlags.InvokeMethod, binder, Container, new object[] { "MockData", new ContainerControlledLifetimeManager() });
My BoostrapperBinder class does this:
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 }); }
Yes, this is ugly, but I just use it for this occasion, so it does the job.
Now the problem is that she still complains about the absence of the third parameter. I can not skip zero or skipped. So, or she wheezes. I tried with BindingFlags.OptionalParamBinding and without it. I'm at a dead end.
(Edited to accommodate the Container.RegisterType example in the code)