简体   繁体   中英

Iterate on implementations of an interface

Is there a way of looping through the multiple implementations of an interface? I haven't written any DI code examples as I didn't want to limit suggestions based on a DI framework. Could be Autofac, Ninject, Unity etc. Whatever is suitable for the task.

I'll be using the ASP.Net Core but I believe the built in DI doesn't allow for multiple implementations.

So, a singular Interface.

public interface InterfaceA
{
    void MethodA();
}

Numerous classes that implement said interface and are registered.

public class Class1 : InterfaceA
{
    public void MethodA()
    {
      //Do something
    }
}

public class Class2 : InterfaceA
{
    public void MethodA()
    {
      //Do something
    }
}

Controller such as this

public TestContoller: Controller
{
    private readonly List<InterfaceA> interfaces;
    void TestController(List<InterfaceA> interfaces)
    {
        this.interfaces = interfaces;
    }

    IActionResult TestMethod()
    {
        Foreach(var implementation in interfaces)
        {
            implementation.MethodA();
        }
        return View();
    }
}

Maybe something like this:

using SimpleInjector;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main (string[] args)
        {
            var container = new Container ();

            container.RegisterCollection<IMyInterface> (new[] { typeof (MyImplementationA), typeof (MyImplementationB) });

            var testController = container.GetInstance<TestController> ();

            testController.TestMethod ();

            Console.ReadKey ();
        }


        public interface IMyInterface
        {
            void DoSomething ();
        }


        public class MyImplementationA : IMyInterface
        {
            public void DoSomething () => Console.WriteLine ("A");
        }


        public class MyImplementationB : IMyInterface
        {
            public void DoSomething () => Console.WriteLine ("B");
        }


        public class TestController
        {
            private readonly IMyInterface[] instances;

            public TestController (InstancesFactory<IMyInterface> factory)
            {
                instances = factory.GetInstances ().ToArray ();
            }

            public void TestMethod ()
            {
                foreach (var instance in instances)
                {
                    instance.DoSomething ();
                }
            }
        }


        public class InstancesFactory<T> where T : class
        {
            private readonly Container container;

            public InstancesFactory (Container container)
            {
                this.container = container;
            }

            public IEnumerable<T> GetInstances ()
            {
                return container.GetAllInstances<T> ();
            }
        }
    }
}

link

I realised there was nothing special required to do what I needed if I used Autofac.

public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc();

        var builder = new ContainerBuilder();

        //  builder.RegisterModule<DataModule>();
        builder.RegisterType<Class1>().As<InterfaceA>();
        builder.RegisterType<Class2>().As<InterfaceA>();

        builder.Populate(services);

        var container = builder.Build();
        return container.Resolve<IServiceProvider>();
    }

Just had to change to the method to return an IServiceProvider rather than a void. (Standard code)

This allowed me to pass in an IEnumerable to my controller constructor which I was able to loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM