温莎城堡类型工厂古怪

时间:2010-12-17 19:50:02

标签: dependency-injection castle-windsor castle

我在Typed Factory工具中遇到了一些非常意外的(我认为)行为。基本上,它使用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。我在这做错了什么?我该怎么做呢?

感谢。

1 个答案:

答案 0 :(得分: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];
        }
    }