2

実装しているすべてのインターフェースに型を登録することは可能ですか?例:私は:

public class Bow : IWeapon
{

    #region IWeapon Members

    public string Attack()
    {
        return "Shooted with a bow";
    }

    #endregion
}

public class HumanFighter 

{
    private readonly IWeapon weapon = null;
    public HumanFighter(IWeapon weapon)
    {
        this.weapon = weapon;
    }

    public string Fight()
    {

        return this.weapon.Attack();
    }

}

    [Test]
    public void Test2b()
    {
        Container container = new Container();
        container.RegisterSingle<Bow>();
        container.RegisterSingle<HumanFighter>();

        // this would match the IWeapon to the Bow, as it
        // is implemented by Bow
        var humanFighter1 = container.GetInstance<HumanFighter>(); 

        string s = humanFighter1.Fight();
    }
4

1 に答える 1

1

それは完全にあなたのニーズに依存しますが、通常あなたはContainerの非一般的な登録方法を使用する必要があります。独自のLINQクエリを定義して、アプリケーションのメタデータをクエリして適切な型を取得し、非ジェネリック登録メソッドを使用してそれらを登録できます。次に例を示します。

var weaponsAssembly = typeof(Bow).Assembly;

var registrations =
    from type in weaponsAssembly.GetExportedTypes()
    where type.Namespace.Contains(".Weapons")
    from service in type.GetInterfaces()
    select new { Service = service, Implementation = type };

foreach (var reg in registrations)
{
    container.Register(reg.Service, reg.Implementation);
}

共有ジェネリックインターフェイスに基づいて一連の実装をバッチ登録する必要がある場合は、RegisterManyForOpenGeneric拡張メソッドを使用できます。

// include the SimpleInjector.Extensions namespace.

container.RegisterManyForOpenGeneric(typeof(IValidator<>),
    typeof(IValidator<>).Assembly);

IValidator<T>これにより、提供されたアセンブリ内で、クローズドジェネリック実装によってそれぞれを実装および登録するすべての(非ジェネリック)パブリック型が検索されます。タイプがの複数のクローズドジェネリックバージョンを実装する場合IValidator<T>、すべてのバージョンが登録されます。次の例を見てください。

interface IValidator<T> { }
class MultiVal1 : IValidator<Customer>, IValidator<Order> { }
class MultiVal2 : IValidator<User>, IValidator<Employee> { }

container.RegisterManyForOpenGeneric(typeof(IValidator<>),
    typeof(IValidator<>).Assembly);

指定されたインターフェイスとクラスの定義を想定すると、表示されるRegisterManyForOpenGeneric登録は、次の手動登録と同等です。

container.Register<IValidator<Customer>, MultiVal1>();
container.Register<IValidator<Order>, MultiVal1>();
container.Register<IValidator<User>, MultiVal2>();
container.Register<IValidator<Employee>, MultiVal2>();

便利な拡張メソッドを追加するのも簡単です。たとえば、実装されているすべてのインターフェイスで単一の実装を登録できる次の拡張メソッドを考えてみましょう。

public static void RegisterAsImplementedInterfaces<TImpl>(
    this Container container)
{
    foreach (var service in typeof(TImpl).GetInterfaces())
    {
        container.Register(service, typeof(TImpl));
    }
}

次のように使用できます。

container.RegisterAsImplementedInterfaces<Sword>();
于 2012-10-18T16:58:46.623 に答える