我的应用程序依赖于多个事件总线对象,这些对象是基本的发布/订阅通知模型 (http://caliburn.codeplex.com/wikipage?title=The%20Event%20Aggregator)。
我想做的是与一组组件共享某个聚合器实例。假设组件我有一个在组件 A、B 和 C 之间共享的事件总线,然后在 D、E、F 之间共享另一个事件总线。
我基本上想将事件总线声明为单例并根据某些标准注入(inject)它们。我有点想避免为了区分分辨率而对事件总线进行子类型化。
我在 Java 中使用了 Google Guice IoC,它允许对参数进行元数据解析。在 Java 中又名,它允许我得到与此等效的东西。
例子:
public A([SpecialUseAggregator]IEventAggregator something)
public B([SpecialUseAggregator]IEventAggregator something)
public E([AnotherUseAggregator]IEventAggregator something)
public F([AnotherUseAggregator]IEventAggregator something)
有什么建议吗?
最佳答案
Autofac 没有/使用注册属性。一种解决方案是使用 Named/Keyed注册功能。
因此您需要注册两个具有不同名称/键的 EventAggreator
并且在注册您的消费者类型 A、B 等时您可以使用 WithParameter
来告诉Autofac IEventAggreator
应该用于给定实例:
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
注册,但是您可以使用 Metadata facility在 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};
}
关于autofac - 根据自定义条件解决依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16114554/