Activator with simple dependency injection In one of my projects I needed a simple dependency incjection activator so I've built one. It performs only type/inheritance matching because I'm not creating a second Autofac and I think I won't need anything more complex any time soon (aka YAGNI).

To find the dependencies I use a Join with a custom comparer. It runs over constructor parameters and tries to match a dependency and maintain the order of the parameters. If the parameters and dependencies counts don't match I use Except to find the missing ones and put their names in the exception message.

I don't use a DI container because I use it for creating commands based on the command line.

public interface IDependencyInjectionActivator
{
    object CreateInstance(Type type, params object[] candidates);
}

public class DependencyInjectionActivator : IDependencyInjectionActivator
{
    private static readonly IEqualityComparer&lt;Type&gt; TypeInheritanceComparer = 
        AdHocEqualityComparer&lt;Type&gt;
            .CreateWithoutHashCode((candidate, parameter) =&gt; parameter.IsAssignableFrom(candidate));

    public object CreateInstance(Type type, params object[] candidates)
    {
        var constructor = type.GetConstructors().Single();

        var parameters =
            constructor
                .GetParameters()
                .Join(
                    candidates,
                    parameter =&gt; parameter.ParameterType,
                    candidate =&gt; candidate.GetType(),
                    (parameter, candidate) =&gt; candidate,
                    TypeInheritanceComparer
                ).ToArray();

        var dependenciesResolved = (parameters.Length == constructor.GetParameters().Length);
        if (dependenciesResolved)
        {
            return Activator.CreateInstance(type, parameters);
        }

        var missingDependencies =
            constructor
                .GetParameters()
                .Select(p =&gt; p.ParameterType)
                .Except(parameters.Select(p =&gt; p.GetType()), TypeInheritanceComparer)
                .ToList();

        var message =
            $"Some dependecies for {type.ToPrettyString().QuoteWith("'")} could not be resolved: " +
            $"{missingDependencies.Select(t =&gt; t.ToPrettyString()).Join(", ").EncloseWith("[]")}";
        throw DynamicException.Factory.CreateDynamicException($"MissingDependency{nameof(Exception)}", message, null);
    }
}


The compare I use here takes two Funcs for each interface method. Factory methods make the creation easier.

public class AdHocEqualityComparer&lt;T&gt; : IEqualityComparer&lt;T&gt;
{
    private readonly Func&lt;T, T, bool&gt; _equals;
    private readonly Func&lt;T, int&gt; _getHashCode;

    private AdHocEqualityComparer(Func&lt;T, T, bool&gt; equals, Func&lt;T, int&gt; getHashCode)
    {
        _equals = equals;
        _getHashCode = getHashCode;
    }

    public static IEqualityComparer&lt;T&gt; CreateWithoutHashCode([NotNull] Func&lt;T, T, bool&gt; equals)
    {
        if (equals == null) throw new ArgumentNullException(nameof(@equals));

        return Create(equals, _ =&gt; 0);
    }

    public static IEqualityComparer&lt;T&gt; Create([NotNull] Func&lt;T, T, bool&gt; equals, [NotNull] Func&lt;T, int&gt; getHashCode)
    {
        if (equals == null) throw new ArgumentNullException(nameof(equals));
        if (getHashCode == null) throw new ArgumentNullException(nameof(getHashCode));

        return new AdHocEqualityComparer&lt;T&gt;(equals, getHashCode);
    }

    public bool Equals(T x, T y)
    {
        if (ReferenceEquals(null, x)) return false;
        if (ReferenceEquals(null, y)) return false;
        if (ReferenceEquals(x, y)) return true;
        return _equals(x, y);
    }

    public int GetHashCode(T obj) =&gt; _getHashCode(obj);
}


This time without examples because I think the usage is strightforward. You create and instance of the activator, specify the type you want to create and pass an array of dependency caditates.

Do you think this DI is smart enough or does it need any improvements?
You are putting pretty strong limitations on classes you can activate this way - a single .ctor, no default .ctor(which can make serialization troubles later) and all .ctor arguments should have different types, otherwise .Join will go crazy. No nested dependencies support, too. No named registrations.

So, all in all, your DI is rather stupid, and if you try to make it smarter, you'll unavoidably end up with "another Autofac".

I went this way once and two months later I wished I hadn't... unless you need to save every byte of RAM, home-made DI surrogate simply doesn't pay off.