根据自定义条件解决依赖关系

时间:2013-04-19 22:45:27

标签: autofac

我的应用程序依赖于多个事件总线对象,这些对象是基本的发布/订阅通知模型(http://caliburn.codeplex.com/wikipage?title=The%20Event%20Aggregator)。

我想要做的是与一组组件共享某些聚合器实例。假设组件我有一个在组件A,B和C之间共享的事件总线,然后是在D,E,F之间共享的另一个事件总线。

我基本上想要将事件总线声明为单例并根据某些条件注入它们。我有点想避免对事件总线进行分类,只是为了区分分辨率。

我在java中使用了Google Guice IoC,它允许参数的元数据解析。在java中的Aka它允许我得到与此相当的东西。

示例:

public A([SpecialUseAggregator]IEventAggregator something)
public B([SpecialUseAggregator]IEventAggregator something)

public E([AnotherUseAggregator]IEventAggregator something)
public F([AnotherUseAggregator]IEventAggregator something)

有什么建议吗?

1 个答案:

答案 0 :(得分:5)

Autofac没有/使用注册属性。一种解决方案是使用Named/Keyed注册功能。

因此,您需要使用不同的名称/密钥注册两个EventAggreator,在注册消费者类型A,B等时,您可以使用WithParameter告诉Autofac {{1}它应该用于给定的实例:

IEventAggreator

我仍然想使用属性,然后你可以使用Autofac,因为它具有所有必需的扩展点,它只需要更多的代码来教授Autofac关于你的属性并正确使用它。

如果您使用扫描注册类型,则无法使用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中使用Metadata facility

只需创建一个保存EventAggreator键的属性:

WithParameter

归因于你的课程:

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

这是gist of a working unit test.