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

次に、2つのインターフェイスを実装するクラスがあります。

class StandardConsole : IStartable, IConsumer<ConsoleCommand>

解決するIStartableと1つのインスタンスを取得し、解決するIConsumer<ConsoleCommand>と別のインスタンスを取得します。

両方のインターフェースで同じインスタンスを取得するにはどうすればよいですか?

4

5 に答える 5

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

Autofacの非常に広く使用されている機能-問題がある場合は、どこかにバグがあります:)

Hthニック

編集見た目では、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を返すラムダ式を登録できるはずです。

何かのようなもの:

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