Activator.CreateInstance - parameterless constructor issue

0

I'm trying to dynamically pull types from an assembly which have a base of EntityTypeConfiguration (Entity Framework-ism). After I have all the types, I want to instantiate an object for each and pass it to a builder (DbModelBuilder) function.

Sample class:

public class LocationConfiguration : EntityTypeConfiguration<Location>
{
    public LocationConfiguration()
    {
        // some basic stuff here
    }
}

I get the types no problem but I get the parameterless constructor error on this line:

var result = (dynamic)Activator.CreateInstance(type);

P.S. I understand in this particular example I could just use AddFromAssembly() but ultimately I want to pick and choose which configurations are loaded.

EDIT:

Adding a hard coded example of line that throws the error:

var result = (dynamic)Activator.CreateInstance(typeof(LocationConfiguration));

EDIT #2:

System.MissingMethodException occurred
  HResult=0x80131513
  Message=No parameterless constructor defined for this object.
  Source=mscorlib
  StackTrace:
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at .OnModelCreating(DbModelBuilder builder) in C:\Development\Context.cs:line 25
   at System.Data.Entity.Internal.LazyInternalContext.CreateModelBuilder()
   at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
   at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
c#
system.reflection
asked on Stack Overflow Jul 20, 2017 by Mark Meisel • edited Jul 20, 2017 by Mark Meisel

1 Answer

2

If the below code is an accurate replication of your problem, then the answer is "because EntityTypeConfiguration creates an instance of Location within its own constructor."

using System;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            object thing = Activator.CreateInstance<PublicCtorClass>();
        }
    }

    class PublicCtorClass : ProtectedCtorGenericClass<PublicParameterisedCtorClass>
    {
        public PublicCtorClass() { }
    }

    class ProtectedCtorGenericClass<T>
    {
        protected ProtectedCtorGenericClass()
        {
            object thing = Activator.CreateInstance(typeof(T));
        }
    }

    class PublicParameterisedCtorClass
    {
        public PublicParameterisedCtorClass(object arg) { }
    }
}

And in that case, the solution would be to create a child class of EntityTypeConfiguration and add a generic constraint to it which limits it to new(). Like this:

class ActivatorSafeEntityTypeConfiguration<T> : EntityTypeConfiguration<T> where T : new()
{

}

Hope this helps!

answered on Stack Overflow Jul 20, 2017 by Dan Rayson

User contributions licensed under CC BY-SA 3.0