我正在使用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);
}
现在一切正常。谢谢!
答案 0 :(得分:1)
您看到的行为是ObservableCollection类型具有接受IEnumerable的构造函数的结果。
您可以使用UsingConstructor()选项将其更改为使用默认构造函数。
ObservableCollection本身可能不是一个非常好的合同,但它有点不清楚语义一般应该是什么。将它包装在具有自己界面的专用组件中是更好的选择。