为多个接口返回相同的实例

时间:2010-07-07 17:51:38

标签: 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.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>

如果我解决了IStartable,我会得到一个实例,如果我解决IConsumer<ConsoleCommand>,我会得到另一个实例。

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

5 个答案:

答案 0 :(得分:60)

builder.RegisterType<StandardConsole>()
   .As<IStartable>()
   .As<IConsumer<ConsoleCommand>>()
   .SingleInstance();

Autofac非常广泛使用的功能 - 任何问题然后在某处出现错误:)

H个 尼克

编辑从外观来看,你是在As()的重载之后采用IEnumerable&lt; Type&gt;() - 使用IntelliSense检查所有的As()重载,应该适合你的场景。正如另一位评论者指出的那样,您需要使用所有信息更新问题。

答案 1 :(得分:2)

更新了尼古拉斯的建议:

以下是在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;
    }

答案 2 :(得分:2)

我知道这是一个旧线程,但这里是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>());

答案 3 :(得分:0)

这是我在黑暗中采取疯狂刺,因为我不知道Autofac。

如果你添加:

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

那么它不应该将ISTartable解析为StandardConsole,然后将StandardConsole解析为StandardConsole的单例实例吗?与IConsumer同上。

编辑:从您在博客上登录,您无法更改以下内容:

assemblies.Each(assembly => assembly.FindComponents((i, c) => builder.RegisterType(c).As(i).SingleInstance()));

assemblies.Each(assembly => assembly.FindComponents((i, c) => {
    builder.RegisterType(c).As(i).SingleInstance();
    builder.RegisterType(c).As(c).SingleInstance();
}));

答案 4 :(得分:0)

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

类似的东西:

builder.Register<IStartable>().As<StandardConsole>().Singleton();
builder.Register<IConsumer<ConsoleCommand>>().As( x => builder.Resolve<IStartable>() );