web-dev-qa-db-ja.com

Castle Windsor:インターフェイスのすべての実装をctorに注入するにはどうすればよいですか?

複数のクラスで実装されるインターフェースを作成しました。登録されているすべての実装がctorに注入されるServiceクラスを作成したいと思います。

私が考えることができる唯一の解決策は、ctor内のService Locatorを呼び出して、すべての実装をResolve()するように依頼することです。

理想的にはこのようなものが欲しいです-

interface IVehicle
{
    void Start();
}

class Car : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Car started.");
    }
}

class Truck : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Truck started.");
    }
}

class Motorbike : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Motorbike started.");
    }
}

class VehicleService
{
    // How do I inject all implementations of IVehicle?
    public VehicleService(IEnumerable<IVehicle> vehicles)
    {
        foreach (var vehicle in vehicles)
        {
            vehicle.Start();
        }
    }
}

[〜#〜] edit [〜#〜]-私はCastleWindsorを使用していることに言及する必要があります。

26
jameskind

CollectionResolverを使用する必要があります。これを確認してください Castle Windsor FAQ

ウィンザーは、デフォルトでIFoo []に依存している場合、IEnumerableまたはIListは、IFooに登録されているコンポーネント(コンポーネントの配列、配列であるコンポーネントと同じではありません)。 CollectionResolverを使用して、「IFooの配列またはリストが表示されたら、取得できるすべてのIFooを取得してください」という動作に変更できます。

Castle Resolversへの直接リンク: Resolvers

28
empi

これはすでに回答済みですが、CollectionResolverを追加する方法の例が役立つと思ったので、ここにあります。

コンテナにコンポーネントを登録する前に、AddSubResolverを呼び出します。

container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

通常どおりコンポーネントを登録します。

container.Register(
    Component.For<IVehicle>().ImplementedBy<Car>(),
    Component.For<IVehicle>().ImplementedBy<Truck>(),
    Component.For<IVehicle>().ImplementedBy<Motorbike>()
);
23

特定のインターフェイスのすべての実装を登録する方法がまだ不足していましたが、この回答は役に立ちました。

お役に立てれば!

container.Register(
            Classes.FromAssemblyContaining<IVehicle>()
                .BasedOn<IVehicle>().WithService.FromInterface()
            );
17
CountZero

ここでの答えはすべて正しいですが、少し余分なしわを追加したかっただけです。サブリゾルバーを追加する必要があります[〜#〜] before [〜#〜]コンポーネントを登録します。

これは機能します:

container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(
    Component.For<IVehicle>().ImplementedBy<Car>(),
    Component.For<IVehicle>().ImplementedBy<Truck>(),
    Component.For<IVehicle>().ImplementedBy<Motorbike>()
);

これは[〜#〜] not [〜#〜]動作します

container = new WindsorContainer();
container.Register(
    Component.For<IVehicle>().ImplementedBy<Car>(),
    Component.For<IVehicle>().ImplementedBy<Truck>(),
    Component.For<IVehicle>().ImplementedBy<Motorbike>()
);
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));