C# – How to check if a type has a default constructor

A default constructor is a constructor that doesn’t have parameters.

Therefore, to check if a type has a default constructor, you can use reflection to loop through the constructors and see if there are any with no parameters, like this:

private static bool HasDefaultConstructor(Type type) { return type.GetConstructors().Any(t => t.GetParameters().Count() == 0); }
Code language: C# (cs)

In this article I’ll show an example of loading types that implement a specific interface – IPlugin – and only load them if they have a default constructor.

IPlugin interface

public interface IPlugin { string HandlesDataFromSource { get; } void ProcessData(string data); }
Code language: C# (cs)

Loading the IPlugin types with default constructors

The following code gets all IPlugin types in the current assembly, then creates an instance if the type has a default constructor.

static void Main(string[] args) { var candidateTypes = GetAllTypesThatImplementInterface<IPlugin>(); Dictionary<string, IPlugin> routingTable = new Dictionary<string, IPlugin>(); foreach(var type in candidateTypes) { if(HasDefaultConstructor(type)) { var plugin = (IPlugin)Activator.CreateInstance(type); routingTable.Add(plugin.HandlesDataFromSource, plugin); Console.WriteLine($"Created type {type.Name}"); } else { Console.WriteLine($"Not creating type {type.Name} - it doesn't have a default constructor"); } } } private static bool HasDefaultConstructor(Type type) { return type.GetConstructors().Any(t => t.GetParameters().Count() == 0); } private static IEnumerable<Type> GetAllTypesThatImplementInterface<T>() { return System.Reflection.Assembly.GetExecutingAssembly() .GetTypes() .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface); }
Code language: C# (cs)

Note: It’s creating a routing table based on what the plugin says it can handle.

Three default constructor scenarios

FileSystemDataHandler plugin – has compiler-generated default constructor

When you don’t declare a constructor, the compiler automatically creates a default constructor for you. When I run the code, it’ll load this plugin because it has a default constructor.

public class FileSystemDataHandler : IPlugin { public string HandlesDataFromSource => "FileSys"; public void ProcessData(string data) { //process data } }
Code language: C# (cs)

HttpDataHandler plugin – has user-defined declared default constructor

In this class I declared a constructor that has no parameters – therefore it’s a default constructor, and this plugin will be loaded when I run the code.

public class HttpDataHandler : IPlugin { public string HandlesDataFromSource => "Http"; public void ProcessData(string data) { //process data } private HashSet<string> wordFilterSet; public HttpDataHandler() { var wordFilterList = ConfigurationManager.AppSettings["wordFilter"].Split(','); wordFilterSet = new HashSet<string>(wordFilterList); } }
Code language: C# (cs)

SqlDataHandler plugin – no default constructor

The following plugin has a constructor with parameters, which means it doesn’t have a default constructor. Because it doesn’t have a default constructor, it will not be loaded.

public class SqlDataHandler : IPlugin { private ConnectionStringSettings ConnectionStringSettings; public SqlDataHandler(ConnectionStringSettings connectionStringSetting) { ConnectionStringSettings = connectionStringSetting; } public string HandlesDataFromSource => "Sql"; public void ProcessData(string data) { //process data } }
Code language: C# (cs)

Results

Running the code results in the following output. As you can see it doesn’t load SqlDataHandler (because it doesn’t have a default constructor, therefore it’s filtered out).

Loading plugins that have a default constructor

Leave a Comment