【问题标题】:Iterate on implementations of an interface迭代接口的实现
【发布时间】:2017-05-18 14:27:34
【问题描述】:

有没有办法循环遍历接口的多个实现?我没有编写任何 DI 代码示例,因为我不想限制基于 DI 框架的建议。可以是 Autofac、Ninject、Unity 等。任何适合该任务的。

我将使用 ASP.Net Core,但我相信内置 DI 不允许多个实现。

所以,一个单一的接口。

public interface InterfaceA
{
    void MethodA();
}

实现所述接口并注册的众多类。

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

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

这样的控制器

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();
    }
}

【问题讨论】:

  • 您是否也在问同样的问题:getting all types that implement an interface ?如果不是,你能解释一下问题出在哪里吗?
  • 我对这些类型并不感兴趣。我给出的代码示例是我想做的假设。我只是不知道是否/哪个 DI 框架可以让我像它一样工作。我在使用 Autofac 的 Orchard CMS 中看到过类似的东西(我认为)。所以也许问题应该是,是否有一个 DI 框架可以让我像我的假设示例一样工作?如果是这样,我将如何注册我的实现?
  • 对,我错过了“已注册”这一点。所以你有收藏。为什么你不能迭代它?您的代码没有编译并且您没有创建实例,所以我不知道您的意图/问题是什么。不过,我没有使用 DI 框架,也许你的问题在了解一个时会更清楚?
  • @Sinatra 它无法编译,可能是因为我在没有方便地使用智能感知的情况下编写了它,我的错。使用 DI,您不会创建实例,如果这是您不熟悉的东西,我强烈建议您看看。即使在我所知甚少的情况下,使用 DI 的好处也非常显着。

标签: c# dependency-injection interface


【解决方案1】:

可能是这样的:

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

【讨论】:

  • 我正在执行 ASP.Net MVC Core 实现,但我会看看是否可以转换。
  • 感谢您对@Apocalypse 的帮助,我确信您的示例有效,但不确定如何转换。最后我找到了一个更简单的解决方案
【解决方案2】:

我意识到,如果我使用 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>();
    }

只需更改方法以返回 IServiceProvider 而不是 void。 (标准代码)

这允许我将一个 IEnumerable 传递给我能够循环的控制器构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-14
    • 2021-09-14
    • 1970-01-01
    • 2014-08-17
    • 2015-06-17
    • 2022-01-10
    • 2013-02-28
    • 2011-12-31
    相关资源
    最近更新 更多