0

Recently, I work with ASP Boilerteample. It has classes to implement dependency injection such as ITransientDependency.

When a class implements the ITransientDependency interface, it can be injected into the constructor without any configuration in the startup file.

I want to do the same but don't know how. Please tell me what to do, is there a library to support or a document.

3
  • A class doesn't inherit from an interface - it implements it...... Commented Apr 24, 2021 at 7:48
  • Do you want repeat the same behavior in some other DI library? Commented Apr 24, 2021 at 7:59
  • Look at this will help you : stackoverflow.com/questions/54490264/… Commented Apr 24, 2021 at 9:32

1 Answer 1

3

You can do this via reflection, however it is not trivial.

The following assumes you have a Dependency Injection container set up.

Step 1

First you need to get all the types from all current assemblies, but only those that are not abstracts or interfaces (i.e. those that can be created):

var types = from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
            where t.IsAssignableFrom(typeof(ITransientDependency))
            && !t.IsAbstract && !t.IsInterface
            select t;

This will return a list of Type objects representing classes that implement ITransientDependency from all currently loaded assemblies.

Step 2

Next, you need to add those to the Dependency Injection container. Assuming you are using Microsoft's IServiceCollection you then do this (e.g. in the ConfigureServices method in your Startup class):

foreach (var t in types)
{
    services.AddTransient(t);
}

Note: this is not really DI best practice. Normally you should inject interfaces, not implementations, and add each one like this:

services.AddTransient<ISomeDependency, SomeImpl>();
services.AddTransient<IAnotherDependency, AnotherImpl>();
// and so on

This helps with test-driven development, as you can create a mock implementation of an interface, but not of an implementation.

Step 3

Finally, you can now inject these into a class via the constructor:

public class SomeClass
{
    public SomeClass(SomeDependency dep)
    {
        // do something
    }
}

You need to be careful doing this as you could introduce issues at runtime - for example, the dependencies of all your ITransientDependency implementations also need to be added to your DI container, and they can't have any other dependencies (e.g. value types).

Warning

The GetTypes() method used in the first step can throw an exception so you would need to handle that. I have done this in the past through pushing this into an extension method:

internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
    try
    {
        return assembly.GetTypes();
    }
    catch (ReflectionTypeLoadException e)
    {
        return e.Types.Where(t => t != null);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. It works, but it's not what I want. This is docs of aspboilerplate
OK, I'm not entirely sure what you're asking then - those docs explain how to register dependencies here - I assumed you were asking how to implement something like what they do?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.