Autofac: добавленная коллекция не пуста (содержит один элемент) - PullRequest
1 голос
/ 05 марта 2011

Я использую 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 <> имеет такое поведение.Но кажется, что подтипы IEnumerable <> также имеют такое поведение.

Но иногда я действительно хочу внедрить коллекцию, например, иногда мне нужно внедрить DispacherNotifiedObservableCollection в мои ViewModels.Есть обходные пути?

Обновление 2:

На основании ответа Николас Блюмхардт я изменил свой код на:

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 Ответ

1 голос
/ 05 марта 2011

Поведение, которое вы видите, является результатом типа ObservableCollection, имеющего конструктор, который принимает IEnumerable.

Вы можете изменить это, чтобы использовать конструктор по умолчанию, используя опцию UsingConstructor ().

ObservableCollection сама по себе может быть не очень хорошим контрактом, от которого можно зависеть - немного неясно, какой вообще должна быть семантика. Лучше всего обернуть его в специализированный компонент с собственным интерфейсом.

...