I'm trying to invoke the RegisterType method in the Unity container. RegisterType has a total of 16 overrides (some of those are parameters some are types).
I'm trying to perform the equivalent of:
Container.RegisterType<IMyDataProvider, MockData.MockProvider>("MockData", new ContainerControlledLifetimeManager())
Using GetMethod() was a total 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 this works beautifully, up until the Invoke which complains because I have no InjectionMember parameters (they're optional and I don't have any to give). So, 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, it's ugly, but I just use it for this oen case, so it does the job.
Now, the problem is, it's still complaining about the lack of a third parameter. I can't pass null or Missing.Value either, or it croaks. I've tried with and without BindingFlags.OptionalParamBinding. I'm stumped.
(Edited to put the Container.RegisterType example in code)