2010-12-17 14 views
0

Ich bekomme etwas sehr unerwartetes (glaube ich) Verhalten mit der Typed Factory Einrichtung. Im Grunde werden vorübergehende Komponenteninstanzen für die Konstruktorinjektion mit Func<T> wiederverwendet. HierCastle Windsor Typed Factory Unheimlichkeit

ist der Kern von ihm:

// this guy is registered as service EntityFrameworkRepositoryProvider, not IRepository 
[Transient] 
public class EntityFrameworkRepositoryProvider : IRepository 
{ 
    public EntityFrameworkRepositoryProvider(ObjectContext objectContext, Assembly assembly) 
    { 
     // HOLY MOLY BATMAN!! Every time I hit this constructor when getProvider gets called, 
     // I don't actually get the arguments passed into getProvider. I get the 
     // arguments that were passed into getProvider the very FIRST time 
     // it was called...in other words I get the wrong 
     // ObjectContext (for the wrong connection string)...BIG PROBLEM 


     // do stuff... 
    } 
} 

[Singleton] 
// this guy gets registered on startup 
internal class EntityFrameworkRepositoryProviderFactory : IRepositoryProviderFactory 
{ 
     private readonly Func<ObjectContext, Assembly, EntityFrameworkRepositoryProvider> getProvider; 

     public EntityFrameworkRepositoryProviderFactory(Func<ObjectContext, Assembly, EntityFrameworkRepositoryProvider> getProvider) 
     { 
      this.getProvider = getProvider; 
      // do stuff... 
     } 

     public IRepository CreateRepository() 
     { 
      var provider = getProvider(new ObjectContext(GetConnectionString()), 
       Assembly.GetExecutingAssembly); 
      // do stuff... 
     } 

     public string GetConnectionString() 
     { 
      // returns one of a few diff EF connection strings 
     }   
} 

Ich habe auch einen Standard LazyComponentLoader. Was mache ich hier falsch? Was soll ich stattdessen tun?

Danke.

Antwort

0

Problem war dieser scheinbar harmlose Code in dem LazyComponentLoader:

 public IRegistration Load(string key, Type service, IDictionary arguments) 
     { 
      var component = Component.For(service); 

      if (!string.IsNullOrEmtpy(key)) 
      { 
       component = component.Named(key); 
      } 

      if (arguments != null) 
      { 
       // This makes the typed factory facility screw up. (Merge is an extension method that merges dictionaries) 
       component.DynamicParameters((k, d) => d.Merge(arguments)); 
      }     

      return component; 
     } 

    public static void Merge(this IDictionary target, IDictionary source) 
    { 
     foreach (object key in source.Keys) 
     { 
      target[key] = source[key]; 
     } 
    } 
+1

hängt, wie Sie Ihre 'Merge' Methode implementieren. Wenn Sie nur Ihre eigenen Argumente zu "d" hinzufügen, sollten Sie in Ordnung sein. Wenn Sie immer noch glauben, dass das Verhalten fehlerhaft ist oder nicht, was Sie erwarten würden, wenden Sie sich an die Castle User Gruppe in Google Groups –

+0

Guter Punkt! Das Problem ist, dass Merge überschreibt, denke ich ... also die erste Reihe von Parametern I Merge() endet das Überschreiben der zweiten (siehe impl oben). – Jeff

+0

... also vielleicht ist das Verhalten zu erwarten (nicht fehlerhaft). – Jeff