Autofac 没有/使用注册属性。一种解决方案是使用命名/键控注册功能。
因此,您需要EventAggreator
使用不同的名称/键为您注册两个,并且在注册您的消费者类型 A、B 等时,您可以使用WithParameter
来告诉 AutofacIEventAggreator
它应该用于给定实例:
var contianerBuilder = new ContainerBuilder();
contianerBuilder.Register(c => CreateAndConfigureSpecialEventAggregator())
.Named<IEventAggreator>("SpecialUseAggregator");
contianerBuilder.Register(c => CreateAndConfigureAnotherUseAggregator())
.Named<IEventAggreator>("AnotherUseAggregator");
contianerBuilder.RegisterType<A>).AsSelf()
.WithParameter(ResolvedParameter
.ForNamed<IEventAggreator>("SpecialUseAggregator"));
contianerBuilder.RegisterType<B>().AsSelf()
.WithParameter(ResolvedParameter
.ForNamed<IEventAggreator>("SpecialUseAggregator"));
contianerBuilder.RegisterType<C>).AsSelf()
.WithParameter(ResolvedParameter
.ForNamed<IEventAggreator>("AnotherUseAggregator"));
contianerBuilder.RegisterType<D>().AsSelf()
.WithParameter(ResolvedParameter
.ForNamed<IEventAggreator>("AnotherUseAggregator"));
var container = contianerBuilder.Build();
如果您仍然想使用属性,那么您可以使用 Autofac 来实现,因为它具有所有必需的扩展点,它只需要更多代码来教 Autofac 您的属性并正确使用它。
如果您使用扫描注册您的类型,则无法使用轻松使用WithParameter
注册,但您使用Autofac中的元数据工具:
只需创建一个属性来保存您的 EventAggreator 键:
public class EventAggrAttribute : Attribute
{
public string Key { get; set; }
public EventAggrAttribute(string key)
{
Key = key;
}
}
并将您的课程归因于:
[EventAggrAttribute("SpecialUseAggregator")]
public class AViewModel
{
public AViewModel(IEventAggreator eventAggreator)
{
}
}
然后,当您进行扫描时,您需要使用WithMetadataFrom
来注册元数据:
contianerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => t.Name.EndsWith("ViewModel"))
.OnPreparing(Method)
.WithMetadataFrom<EventAggrAttribute>();
最后,您需要进行OnPreparing
基于元数据的解析的事件:
private void Method(PreparingEventArgs obj)
{
// Metadata["Key"] is coming from the EventAggrAttribute.Key
var key = obj.Component.Metadata["Key"].ToString();
ResolvedParameter resolvedParameter =
ResolvedParameter.ForNamed<IEventAggreator>();
obj.Parameters = new List<Parameter>() { resolvedParameter};
}
这是工作单元测试的要点。