2011-03-05 7 views
1

J'utilise Autofac 2.4.4.705.Autofac: La collection injectée n'est pas vide (contient un article)

La sortie du code suivant: 1 (. Ce qui signifie que la collecte résolue contient un élément que je pense qu'il devrait être vide)

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<>)); 
    } 
} 

Il semble que le problème est causé par:

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()); 

Si je le retire d'AutofacModule, la sortie est 0.

Des idées?

Merci

Mise à jour:

Ah, je crois que je comprends maintenant. Autofac pensait que je voulais résoudre tous les types de A, et il y a un type de A dans cet exemple (A lui-même), donc ObservableCollection contient un élément. Je pensais précédemment que seul IEnumerable <> a ce comportement. Mais il semble que les sous-types de IEnumerable < ont aussi ce comportement.

Mais parfois, ce que je veux vraiment, c'est injecter une collection, par exemple, parfois je dois injecter DispacherNotifiedObservableCollection dans mes ViewModels. Des solutions de contournement?

Mise à jour 2:

Sur la base de la réponse de Nicholas Blumhardt, j'ai changé mon code pour:

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); 
} 

Maintenant, tout fonctionne bien. Merci!

Répondre

1

Le comportement que vous voyez est le résultat du type ObservableCollection dont le constructeur accepte IEnumerable.

Vous pouvez modifier cela pour utiliser le constructeur par défaut à l'aide de l'option UsingConstructor(). ObservableCollection lui-même n'est peut-être pas un très bon contrat sur lequel s'appuyer - il est un peu difficile de savoir ce que la sémantique devrait être généralement. Envelopper dans un composant spécialisé avec sa propre interface est la meilleure option.

Questions connexes