0

I having problem calling my constructor with reflection. The parameterless constructor is no problem but when I'm trying to call the once which has parameter I get missingMethodException.

Code:

 if (type != null)
        {
            var constructor = type.GetConstructor(Type.EmptyTypes);
            if (constructor != null)
               return Activator.CreateInstance(type);

            constructor = type.GetConstructors()[0];

            var parameters = constructor.GetParameters();

            var obj = new object[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                obj[i] = (object) parameters[i].ParameterType;
            }
            return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, null);
        }

The parameterless constructor works fine.

 var constructor = type.GetConstructor(Type.EmptyTypes);
            if (constructor != null)
            {
                return Activator.CreateInstance(type);
            }

This part does not:

   constructor = type.GetConstructors()[0];

            var parameters = constructor.GetParameters();

            var obj = new object[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                obj[i] = (object) parameters[i].ParameterType;
            }
            return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, null);
        }

I know that one of the constructors looks like this:

 public class YYY: XXX
{
    public YYY(Guid customerId)
        : base(404, Level.Warn, null, string.Format("{0}",customerId))
    {
    }
}

I also know that the parameterType is not the datatype that the constructor wants:

parameters[i].ParameterType is Guid
false

And.. I know that if I remove obj and put new Guid() it will work:

return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Guid(), null);

Question: How can I call the constructor?

raholsn
  • 658
  • 1
  • 7
  • 15
  • possible duplicate of [Using C# reflection to call a constructor](http://stackoverflow.com/questions/3255697/using-c-sharp-reflection-to-call-a-constructor) – M.Babcock Jul 22 '15 at 18:03
  • @M.Babcock Yes I've seen it. They are using hard coded integers when they calling the constructor. I'm trying to call the constructor with types from ParameterInfo[] – raholsn Jul 22 '15 at 18:07
  • 2
    Why are you putting `Type` instances in the parameter array then expecting to call a constructor which takes a `Guid`? A `Type` is no convertable to a `Guid` How would you ever expect this to work? – Dark Falcon Jul 22 '15 at 18:11
  • Not sure how it works.., can you give me a exemple on how to call the constructor with the correct type? – raholsn Jul 22 '15 at 18:20
  • @user2538364 You do not call the constructor with a type parameter, you need a `Guid` instance to pass to the `Activator.CreateInstance()` method. Where are you supposed to get the `Guid` to create your instance of `YYY`? – Sven Grosen Jul 22 '15 at 18:22
  • I though it was possible to get the guid type from type parameterinfo. And that where I got stuck. – raholsn Jul 22 '15 at 18:29

1 Answers1

0

Found some clues from:

How to identify each parameter type in a C# method?

Where @JaredPar saying the following: To get the actual Type of the parameter use the ParameterType on the ParameterInfo value. With that value there are several ways you can use it to identify the type. The easiest is with a direct comparison to a known type.

So in my case I need to Identify the type of the parameterType and create a new instance of that type before I send it to the constructor.

Because I only care of the type of the object, I could resolve it by

var fixture = new Fixture(); //Ploeh.AutoFixture
var obj = new SpecimenContext(fixture).Resolve(asmtype); //Ploeh.AutoFixture.Kernel.SpecimenContext 

So after getting the assemblytype I just create a fixture and a specimentContext with fixture and then resolve the asmType.

This object will be of the corresponding type.

So Final result:

   foreach (var asmtype in assemblyTypes)
        {
            var fixture = new Fixture();
            var obj = new SpecimenContext(fixture).Resolve(asmtype);

            _handler.Error(new Login { BrandId = _brandId }, new Domain.Entities.Customer { CustomerId = It.IsAny<Guid>() }, (Exception) obj);

            if (obj is InvalidCredentialsException)
                _loginRepository.Verify(v => v.ZZZ(It.IsAny<Guid>(), It.IsAny<int>()), Times.Once);
            else
                _loginRepository.Verify(v => v.ZZZ(It.IsAny<Guid>(), It.IsAny<int>()), Times.Never);
        }
Community
  • 1
  • 1
raholsn
  • 658
  • 1
  • 7
  • 15