2014-09-30 63 views
3

我有以下的StructureMap註冊工作在版本2.6.4,我終於升級到最新的SM(本文撰寫時爲3.1.2)。並且需要更新它,因爲不再有IContext.BuildStack。StructureMap 3獲取請求的類型

這裏是舊的工作版本2.6.4:

 initialization.For(typeof(IRepository<,>)) 
          .Use(context => 
          { 
           var genericArgs = context.BuildStack.Current.RequestedType.GetGenericArguments(); 

           return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1], repositoryName); 
          } 
      ); 

所以我想它更改爲這會工作:

 initialization.For(typeof (IRepository<,>)) 
      .Use("IRepository<,>", context => 
            { 
             var genericArgs = context.ParentType.GetGenericArguments(); 

             return RepositoryFactory.GetInstance(genericArgs[0], genericArgs[1], 
              repositoryName); 
            } 
      ); 

但context.ParentType爲空。當我看context.RootType時,它被設置爲System.Object,這顯然不是我想要的。

我的測試代碼來獲得這個倉庫的一個實例是:

var userRepository = ObjectFactory.GetInstance<IRepository<User, Guid>>(); 

我看不出有此信息的任何其他財產,但我猜,我失去了一些東西。

回答

6

你不會錯過什麼。在GitHub上,有人發佈了一個類似的問題:https://github.com/structuremap/structuremap/issues/288。 結構圖作者Jeremy Miller迴應道:

這將是新的發展。它將不得不在3.2版本。

建議的解決方法是創建一個自定義實例並覆蓋ClosingType方法。你可以做到這一點,如下所示:

public class CustomInstance : Instance 
{ 
    public override IDependencySource ToDependencySource(Type pluginType) 
    { 
     throw new NotImplementedException(); 
    } 

    public override Instance CloseType(Type[] types) 
    { 
     var repository = RepositoryFactory.GetInstance(types[0], types[1], repositoryName);               
     return new ObjectInstance(repository); 
    } 

    public override string Description 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public override Type ReturnedType 
    { 
     get { return typeof (IRepository<,>); } 
    } 
} 

現在,你只需要在開放式泛型類型連接到封閉式這樣的:

initialization.For(typeof (IRepository<,>)).Use(new CustomInstance()); 
+0

感謝您指出。 該解決方法如何解決不起作用?看起來好像我創建了一個自定義實例並實現了CloseType重寫,那麼我就可以訪問那裏的泛型類型,並可以使用適當的類型調用我的RepositoryFactory。我不知道要從CloseType返回什麼,因爲它期望的是實例而不是對象。 – 2014-10-06 19:24:24

+0

你說得對。我採取了更好的看法,解決方法確實奏效。我已經更新了答案。 – 2014-10-06 21:05:21

+0

太棒了。今晚我會給你一個鏡頭,並確保它能正常工作。我沒有意識到新的ObjectInstance()語法,並且被卡住了。謝謝! – 2014-10-07 01:47:01

4

我添加了一個新的例子在StructureMap 3代碼庫這種情況下根據你的問題:

https://github.com/structuremap/structuremap/blob/master/src/StructureMap.Testing/Acceptance/builder_for_open_generic_type.cs

我要問,雖然,有什麼東西的目的,像RepositoryBuilder如果y你在使用IoC容器嗎?

無論如何,這個實現應該比舊的Reflection-heavy方法更高效。

+0

它是一個通用的存儲庫,它可以通過配置文件配置來替換後端的SharpRepository以及緩存設置。所以我想注入IRepository 並使用RepositoryFactory解決它,因爲它使用配置數據來確定要實現的實際類型。因此用戶可以更新配置文件來更改內容而不是更新代碼。它可以通過Redis緩存或內存中緩存等方式解析爲EfRepository 或MongoDbRepository 或InMemory 。 – 2014-10-07 16:30:17