SimpleInjector - 为所有接口注册一个类型

时间:2012-10-18 16:13:58

标签: dependency-injection simple-injector

是否可以为所有实现接口注册一个类型?例如,我有一个:

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

1 个答案:

答案 0 :(得分: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>();