37

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

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>我得到另一个。

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

4

5 回答 5

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

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

第尼克

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

于 2010-07-07T22:56:30.387 回答
3

更新了尼古拉斯的建议:

这是在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;
    }
于 2010-07-08T16:29:27.230 回答
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>());
于 2011-07-14T15:22:17.547 回答
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();
}));
于 2010-07-07T18:32:55.930 回答
0

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

就像是:

builder.Register<IStartable>().As<StandardConsole>().Singleton();
builder.Register<IConsumer<ConsoleCommand>>().As( x => builder.Resolve<IStartable>() );
于 2010-07-07T18:33:37.123 回答