2010-12-17 61 views
0

我得到了一些非常意想不到的(我認爲)與類型工廠設施的行爲。基本上,它將Func<T>用於構造器注入的瞬態組件實例。城堡溫莎輸入工廠古怪

下面是它的要點:

// 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 
     }   
} 

我也有一個標準的LazyComponentLoader。我在這裏做錯了什麼?我該怎麼做呢?

謝謝。

回答

0

的問題是在這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

取決於你如何實現你的'Merge'方法。如果你只是將自己的參數添加到'd',你應該沒問題。如果你仍然相信這個行爲有點不對,或者你不期望可以隨意提出這個問題,就Google羣組上的Castle用戶組進行討論 – 2010-12-17 23:35:14

+0

好點!問題是Merge會覆蓋我認爲的...所以第一組參數I Merge()最終覆蓋第二個參數(參見上面的impl)。 – Jeff 2010-12-18 02:43:34

+0

...所以也許這種行爲是可以預料的(沒有缺陷)。 – Jeff 2010-12-18 02:49:55