Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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#_Singleton_Autofac - Fatal编程技术网

C# 为多个接口返回同一实例

C# 为多个接口返回同一实例,c#,singleton,autofac,C#,Singleton,Autofac,我正在使用以下代码注册组件: StandardKernel kernel = new StandardKernel(); string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location) foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!Path.GetDirectoryName(assembly.Loc

我正在使用以下代码注册组件:

StandardKernel kernel = new StandardKernel();

string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location)
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
    if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory)) 
        continue;

    foreach (var type in assembly.GetTypes())
    {
        if (!type.IsComponent()) 
            continue;

        foreach (var @interface in type.GetInterfaces())
        kernel.Bind(@interface).To(type).InSingletonScope();
    }
}
然后我有一个实现两个接口的类:

class StandardConsole : IStartable, IConsumer<ConsoleCommand>
class StandardConsole:IStartable,IConsumer
如果我解析
IStartable
我会得到一个实例,如果我解析
IConsumer
我会得到另一个实例


如何为两个接口获得相同的实例?

这是我在暗中摸索,因为我不知道Autofac

如果您添加:

build.RegisterType<StandardConsole>.As(StandardConsole).SingleInstance()


我不熟悉Autofac,但您应该能够为一种类型注册一个lambda表达式,该表达式返回另一种类型的解析

比如:

builder.Register<IStartable>().As<StandardConsole>().Singleton();
builder.Register<IConsumer<ConsoleCommand>>().As( x => builder.Resolve<IStartable>() );
builder.Register().As().Singleton();
builder.Register().As(x=>builder.Resolve());
builder.RegisterType()
.As()
.As()
.SingleInstance();
Autofac使用非常广泛的功能-如果出现任何问题,则在某个地方会出现错误:)

嗯 尼克


编辑从外观上看,您正在寻找需要IEnumerable()的As()重载-使用IntelliSense检查所有As()重载,那里应该适合您的场景。另一位评论者指出,你需要用所有信息更新问题。

根据尼古拉斯的建议更新:

下面是如何在autofac中完成的

    private void BuildComponents(ContainerBuilder builder)
    {
        string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory))
                continue;

            builder.RegisterAssemblyTypes(assembly)
                .Where(t => t.IsComponent())
                .AsImplementedInterfaces()
                .SingleInstance();
        }
    }

    public static bool IsComponent(this Type value)
    {
        return value.GetType().GetCustomAttributes(typeof (ComponentAttribute), true).Length > 0;
    }

我知道这是一个旧线程,但这里是Ninject的解决方案

kernel.Bind<StandardConsole>().ToSelf().InSingletonScope();
kernel.Bind<IStartable>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());
kernel.Bind<IConsumer<ConsoleCommand>>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());
kernel.Bind().ToSelf().InSingletonScope();
kernel.Bind().ToMethod(ctx=>ctx.kernel.Get());
kernel.Bind().ToMethod(ctx=>ctx.kernel.Get());

不行。我在使用ComponentAttribute的类之后扫描应用程序目录中的所有程序集,并用它们实现的所有接口注册它们。那就很难按照你的建议去做了。请参阅我对dave thiebenNo的评论,我不想使用IEnumerable注册。这是autofac的内置功能。另外,我不能使用泛型参数,因为我使用反射来注册所有组件。我知道你的意思(我写的;)-我建议的功能是不同的。如果您有一个要公开的接口列表(i1、i2、i3..),您可以将整个列表传递给一个As()调用。您还可以查看RegisterAssemblyTypes(myAsm).AsImplementedInterfaces(),它可以扩展到您的文章所建议的内容-如果您愿意,欢迎您通过Autofac讨论论坛来完成此工作。抱歉=)只是厌倦了没有使用Autofac的人的回答。我已经用扫描文章中的代码更新了下面的答案。谢谢这个问题应该分为两个部分,一个是Ninject,另一个是autofac。@JeffWalkerCodeRanger:你给了-1分吗?:)Ninject侧有3或4个DUP,请参见在此基础上删除的Ninject标记。建议从问题中删除ninject方面,因为这会导致无法回答的问题question@Jeff:见
builder.RegisterType<StandardConsole>()
   .As<IStartable>()
   .As<IConsumer<ConsoleCommand>>()
   .SingleInstance();
    private void BuildComponents(ContainerBuilder builder)
    {
        string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory))
                continue;

            builder.RegisterAssemblyTypes(assembly)
                .Where(t => t.IsComponent())
                .AsImplementedInterfaces()
                .SingleInstance();
        }
    }

    public static bool IsComponent(this Type value)
    {
        return value.GetType().GetCustomAttributes(typeof (ComponentAttribute), true).Length > 0;
    }
kernel.Bind<StandardConsole>().ToSelf().InSingletonScope();
kernel.Bind<IStartable>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());
kernel.Bind<IConsumer<ConsoleCommand>>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());