0

I am using .net core, I got a simple Interface something like :

public interface ITask
{
    string TaskName { get; }
    void Execute(TaskDetails item);
}

I got many classes which implement it, a sample class :

public class Task1Adapter : ITaskAdapter
{

    public string TaskName => "MyTask...";

    public void Execute(TaskDetails item)
    {
         var x = 1 + 1;
    } 
}

Then i got the DI section in which i add a line for each class -

services.AddSingleton<ITaskAdapter, Task1Adapter>();

My problem is that I got quite a lot of tasks and If possible I would rather avoid having 100+ AddSingleton lines.

Is there a way to somehow add all of the classes which implement that interface in one go without having to add AddSingleton logic for each new class I am adding?

Edit: Since I need to call different tasks / classes that implement the interface dynamically I used the following logic in run time -

private readonly IEnumerable<IFilesWorkerAdapter> _taskAdapter;
_taskAdapter.FirstOrDefault(e => e.TaskName== taskNameFromExternalSource).Execute();
3
  • You can use reflection to find all classes derived from that interface and add it to the services collection. Commented May 2, 2019 at 10:48
  • Use factory pattern to instantiate a concrete class of an interface. Profit serviceProvider to get the instance configured. @Nkosi comment will allow you to register each class but I advice you register the class not the pair Interface, Class. Make the factory to decide witch class to instantiate. Commented May 2, 2019 at 10:52
  • I added another part to the question to make it clearer. I not sure if your comment still valid with that in mind. Can you guys add a minimal example for the reflection logic? Commented May 4, 2019 at 15:04

2 Answers 2

1

You can use Ninject with convention names. Check the following example:

https://github.com/jhonmarmolejo/DemoMVC/blob/master/Demo.MVC/App_Start/NinjectWebCommon.cs

In line number 57, I implemented all interfaces according to a specific rule

  /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind(ker =>
        {
            ker.FromAssembliesMatching("*Business.Implementation*").SelectAllClasses().BindAllInterfaces();
        });
    }        

To use it, you'll need the following nuget:

https://www.nuget.org/packages/Ninject.Extensions.Conventions/

I hope it helps you Regards Jhon

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the answer, I am pretty deep with the 'native' supplied .net core DI logic and I dont want to make any big changes to that.
0

Update of my previous response: .NET Core allows registering your implementations using reflection

        services.Scan(scan => scan
            .FromAssemblyOf<EmailService>()
            .AddClasses(classes => classes.Where(c => c.Name.EndsWith("Service")))
            .UsingRegistrationStrategy(RegistrationStrategy.Skip)
            .AsImplementedInterfaces()
            .WithSingletonLifetime());

You only need to do the following steps:

  • Indicate one class where the ServiceCollection needs to get the other implementations, in my case 'EmailService'.
  • To have a convention names, in my case "Service" at the end of the classes names.

Comments

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.