Autofac:注入的集合不为空(包含一个项目)

时间:2011-03-05 03:03:51

标签: autofac

我正在使用Autofac 2.4.4.705。

以下代码的输出为:1(表示已解析的集合包含一个项目。我认为它应该为空)

class Program
{
    static void Main(string[] args)
    {
        var builder = new Autofac.ContainerBuilder();
        builder.RegisterModule(new AutofacModule());
        using (var container = builder.Build())
        {
            var x = container.Resolve<ObservableCollection<A>>();
            Console.WriteLine(x.Count);
        }
    }
}

class A
{
}

class AutofacModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());
        builder.RegisterGeneric(typeof(ObservableCollection<>))
            .As(typeof(ObservableCollection<>));
    }
}

似乎问题是由以下原因造成的:

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());

如果我从AutofacModule中删除它,则输出为0.

有什么想法吗?

由于

<德尔>的更新

啊,我想我现在明白了。 Autofac认为我想要解析所有类型的A,并且在这个例子中有一种类型的A(A本身),所以ObservableCollection包含一个项目。我之前认为只有IEnumerable&lt;&gt;有这种行为。但它似乎是IEnumerable&lt;&gt;的子类型也有这种行为。

但有时我真正想要的是注入一个集合,例如,有时我需要将DispacherNotifiedObservableCollection注入到我的ViewModel中。任何解决方法?

更新2:

根据Nicholas Blumhardt的答案,我将代码更改为:

builder.RegisterGeneric(typeof(ExtendedObservableCollection<>))
    .As(typeof(IObservableCollection<>))
    .UsingConstructor();

public interface IObservableCollection<T> : 
    IList<T>, ICollection<T>, IEnumerable<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
    void AddRange(IEnumerable<T> list);
    void Sort<TKey>(Func<T, TKey> keySelector, System.ComponentModel.ListSortDirection direction);
    void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer);
}

现在一切正常。谢谢!

1 个答案:

答案 0 :(得分:1)

您看到的行为是ObservableCollection类型具有接受IEnumerable的构造函数的结果。

您可以使用UsingConstructor()选项将其更改为使用默认构造函数。

ObservableCollection本身可能不是一个非常好的合同,但它有点不清楚语义一般应该是什么。将它包装在具有自己界面的专用组件中是更好的选择。