是否可以为所有实现接口注册一个类型?例如,我有一个:
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();
}
答案 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>();