Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取所有已实现接口的列表_C#_.net_Dependency Injection_Interface - Fatal编程技术网

C# 获取所有已实现接口的列表

C# 获取所有已实现接口的列表,c#,.net,dependency-injection,interface,C#,.net,Dependency Injection,Interface,我有3个具有相同接口的类: cppTopicGenerator : TopicGenerator phpTopicGenerator : TopicGenerator javaTopicGenerator : TopicGenerator 我为他们创建了一个门面,我试着使用它们,如下所示: public class MyFacade { private readonly List<TopicGenerator> generators; public void B

我有3个具有相同接口的类:

cppTopicGenerator : TopicGenerator
phpTopicGenerator : TopicGenerator
javaTopicGenerator : TopicGenerator
我为他们创建了一个门面,我试着使用它们,如下所示:

public class MyFacade 
{
    private readonly List<TopicGenerator> generators;

    public void BusinessLogic(string extension)
    {
            MyParser(extenstion).generate();
    }


    private TopicGenerator MyParser(string extension)
    {
        foreach (var generator in generators)
        {
            if (generator.Accept(extension))
            {
                return generator;
            }
        }
        throw new NotFoundException($"Generator for {extension} doesnt exist.");
    }
}
问题是,我们应该如何创建这个生成器列表?我需要手动创建所有生成器的列表,如:

private readonly List<TopicGenerator> generators = new List(
        {
            new CppTopicGenerator()
            new PhpTopicGenerator()
            new JavaTopicGenerator()
        });

或者可以自动注入它们吗?

当然可以,您可以通过IoC容器注入。但是,这取决于你的需要。如果您的生成器太复杂,需要大量参考,您可以使用IoCe.x,但如果它是轻量级的,我更喜欢手动创建它

示例控制台应用程序中的所有示例: 1手动

using System;
using System.Collections.Generic;

namespace Test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var service = new MyFacade();

            service.MyParser("foo");
            service.MyParser("bar");
            service.MyParser("foobar");
        }
    }

    public class MyFacade
    {
        private readonly IEnumerable<IGenerator> _generators;

        public MyFacade()
        {
            _generators = new List<IGenerator>()
            {
                new CppTopicGenerator(),
                new PhpTopicGenerator(),
                new JavaTopicGenerator(),
            };
        }

        public IGenerator MyParser(string extension)
        {
            foreach (var generator in _generators)
            {
                if (generator.Accept(extension))
                {
                    return generator;
                }
            }

            throw new NotFoundException($"Generator for {extension} doesnt exist.");
        }
    }

    public interface IGenerator
    {
        bool Accept(string extension);
    }

    public class CppTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("CppTopicGenerator checking executed");
            return extension == "foo";
        }
    }

    public class PhpTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("PhpTopicGenerator checking executed");
            return extension == "bar";
        }
    }

    public class JavaTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("JavaTopicGenerator checking executed");
            return extension == "foobar";
        }
    }
}
2自动传真:

class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var builder = new ContainerBuilder();

            builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies()).As<IGenerator>();
            builder.RegisterType<MyFacade>();

            var container = builder.Build();

            using (var scope = container.BeginLifetimeScope())
            {
                var service = scope.Resolve<MyFacade>();

                service.MyParser("foo");
                service.MyParser("bar");
                service.MyParser("foobar");
            }
        }
    }

    public class MyFacade
    {
        private readonly IEnumerable<IGenerator> _generators;

        public MyFacade(IEnumerable<IGenerator> generators)
        {
            _generators = generators;
        }

        public IGenerator MyParser(string extension)
        {
            foreach (var generator in _generators)
            {
                if (generator.Accept(extension))
                {
                    return generator;
                }
            }

            throw new NotFoundException($"Generator for {extension} doesnt exist.");
        }
    }

    public interface IGenerator
    {
        bool Accept(string extension);
    }

    public class CppTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("CppTopicGenerator checking executed");
            return extension == "foo";
        }
    }

    public class PhpTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("PhpTopicGenerator checking executed");
            return extension == "bar";
        }
    }

    public class JavaTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("JavaTopicGenerator checking executed");
            return extension == "foobar";
        }
    }

当然可以,您可以通过IoC容器注入它。但是,这取决于你的需要。如果您的生成器太复杂,需要大量参考,您可以使用IoCe.x,但如果它是轻量级的,我更喜欢手动创建它

示例控制台应用程序中的所有示例: 1手动

using System;
using System.Collections.Generic;

namespace Test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var service = new MyFacade();

            service.MyParser("foo");
            service.MyParser("bar");
            service.MyParser("foobar");
        }
    }

    public class MyFacade
    {
        private readonly IEnumerable<IGenerator> _generators;

        public MyFacade()
        {
            _generators = new List<IGenerator>()
            {
                new CppTopicGenerator(),
                new PhpTopicGenerator(),
                new JavaTopicGenerator(),
            };
        }

        public IGenerator MyParser(string extension)
        {
            foreach (var generator in _generators)
            {
                if (generator.Accept(extension))
                {
                    return generator;
                }
            }

            throw new NotFoundException($"Generator for {extension} doesnt exist.");
        }
    }

    public interface IGenerator
    {
        bool Accept(string extension);
    }

    public class CppTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("CppTopicGenerator checking executed");
            return extension == "foo";
        }
    }

    public class PhpTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("PhpTopicGenerator checking executed");
            return extension == "bar";
        }
    }

    public class JavaTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("JavaTopicGenerator checking executed");
            return extension == "foobar";
        }
    }
}
2自动传真:

class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var builder = new ContainerBuilder();

            builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies()).As<IGenerator>();
            builder.RegisterType<MyFacade>();

            var container = builder.Build();

            using (var scope = container.BeginLifetimeScope())
            {
                var service = scope.Resolve<MyFacade>();

                service.MyParser("foo");
                service.MyParser("bar");
                service.MyParser("foobar");
            }
        }
    }

    public class MyFacade
    {
        private readonly IEnumerable<IGenerator> _generators;

        public MyFacade(IEnumerable<IGenerator> generators)
        {
            _generators = generators;
        }

        public IGenerator MyParser(string extension)
        {
            foreach (var generator in _generators)
            {
                if (generator.Accept(extension))
                {
                    return generator;
                }
            }

            throw new NotFoundException($"Generator for {extension} doesnt exist.");
        }
    }

    public interface IGenerator
    {
        bool Accept(string extension);
    }

    public class CppTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("CppTopicGenerator checking executed");
            return extension == "foo";
        }
    }

    public class PhpTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("PhpTopicGenerator checking executed");
            return extension == "bar";
        }
    }

    public class JavaTopicGenerator : IGenerator
    {
        public bool Accept(string extension)
        {
            Console.WriteLine("JavaTopicGenerator checking executed");
            return extension == "foobar";
        }
    }

您可以从程序集反映它们,然后通过Activator实例化它们:

    public MyFacade() {
        //Reflect them
        var type = typeof(TopicGenerator);
        var types = AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(s => s.GetTypes())
        .Where(p => type.IsAssignableFrom(p) && !p.IsInterface);
        //Instantiate them
        generators = types.Select(t => Activator.CreateInstance(t) as TopicGenerator).ToList();
    }

通过这种方式,您将找到实现TopicGenerator的所有类,如果您创建了一个新类,则无需手动添加它们。

您可以从程序集中反映它们,然后通过Activator实例化它们:

    public MyFacade() {
        //Reflect them
        var type = typeof(TopicGenerator);
        var types = AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(s => s.GetTypes())
        .Where(p => type.IsAssignableFrom(p) && !p.IsInterface);
        //Instantiate them
        generators = types.Select(t => Activator.CreateInstance(t) as TopicGenerator).ToList();
    }
通过这种方式,您将找到实现TopicGenerator的所有类,如果您创建了一个新类,则无需手动添加它们。

您可以使用来实现这一点

private static readonly List<TopicGenerator> generators = 
    Assembly.GetExecutingAssembly().GetTypes()
        .Where(x => x.ImplementedInterfaces.Contains(typeof(TopicGenerator)))
        .Select(x => (TopicGenerator)Activator.CreateInstance(x))
        .ToList();
您可以使用来实现这一点

private static readonly List<TopicGenerator> generators = 
    Assembly.GetExecutingAssembly().GetTypes()
        .Where(x => x.ImplementedInterfaces.Contains(typeof(TopicGenerator)))
        .Select(x => (TopicGenerator)Activator.CreateInstance(x))
        .ToList();

您可以使用以下命令生成列表

var list = AppDomain.CurrentDomain.GetAssemblies()
                    .SelectMany(x => x.GetTypes())
                    .Where(p => typeof(TopicGenerator).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract)
                    .Select(x => (TopicGenerator)Activator.CreateInstance(x)).ToList<TopicGenerator>();

它所做的是,反映和迭代汇编中的类型,并检查是否实现了特定的接口。这个p、 IsAbstract将确保不列出抽象类。

您可以使用以下命令生成列表

var list = AppDomain.CurrentDomain.GetAssemblies()
                    .SelectMany(x => x.GetTypes())
                    .Where(p => typeof(TopicGenerator).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract)
                    .Select(x => (TopicGenerator)Activator.CreateInstance(x)).ToList<TopicGenerator>();

它所做的是,反映和迭代汇编中的类型,并检查是否实现了特定的接口。这个p、 IsAbstract将确保不列出抽象类。

您将如何使用它们?如何在代码中知道是否需要CppTopicGenerator或PhpTopicGenerator?主题生成器接口有两个方法,其中一个是generate,这是我的业务逻辑,第二个是Acceptstring扩展,我将使用该生成器,某些服务容器实现允许您为同一接口添加多个注册,然后依赖IEnumerable获取包含所有具体实现的集合。因为你没有说你正在使用哪个容器库,所以不可能说这是否可能使用它。你将如何使用它们?如何在代码中知道是否需要CppTopicGenerator或PhpTopicGenerator?主题生成器接口有两个方法,其中一个是generate,这是我的业务逻辑,第二个是Acceptstring扩展,我将使用该生成器,某些服务容器实现允许您为同一接口添加多个注册,然后依赖IEnumerable获取包含所有具体实现的集合。由于您没有说明使用的是哪个容器库,因此无法确定是否可以使用它。如果TopicGenerator确实是一个接口而不是类,则x.BaseType==…将不起作用。如果TopicGenerator确实是一个接口而不是类,那么x.BaseType==…将不起作用。你能给我举个例子吗?@degath与autofac的关系如何?这就是你需要的谢谢,给我点时间检查一下。你能给我举个例子吗?@degath with autofac?这是你需要的谢谢,给我点时间检查一下。