2016-06-22 61 views
0

我想要了解如何在StructureMap中使用策略工作的example 2。我創建了一個小測試項目(代碼如下)。不幸的是由於某種原因,似乎有一些依賴性問題,因爲.As<type>.Each都不起作用。在StructureMap中使用策略的示例缺少依賴關係

對於使用As

user.Green.As<Database>().ConnectionString.ShouldBe("*green*"); 

我收到錯誤行:

'IDatabase' does not contain a definition for 'As' and no extension method 'As' accepting a first argument of type 'IDatabase' could be found (are you missing a using directive or assembly reference?). And for this line:

instance.Constructor.GetParameters() 
       .Where(x => x.ParameterType == typeof(IDatabase)) 
       .Each(param => ... 

'StringExtensions.Each(IEnumberable,Action)' is inaccessible due to its protection level.

我安裝StructureMap 4.2使用的NuGet。正如你在下面的代碼中看到的那樣,我把所有可以找到的StructureMap中的所有using表達式都放進去了,但是我仍然遇到了這個問題。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using StructureMap; 
using StructureMap.Pipeline; 
using StructureMap.Pipeline.Lazy; 
using StructureMap.Configuration; 
using StructureMap.Building; 
using StructureMap.Attributes; 
using StructureMap.AutoMocking; 
using StructureMap.Graph; 
using StructureMap.Query; 
using StructureMap.TypeRules; 
using StructureMap.Util; 
using StructureMap.Building.Interception; 
using StructureMap.Configuration.DSL; 
using StructureMap.Diagnostics.TreeView; 
using StructureMap.Graph.Scanning; 

namespace TestStructureMapPolicies 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var container = new Container(_ => 
      { 
       _.For<IDatabase>().Add<Database>().Named("red") 
        .Ctor<string>("connectionString").Is("*red*"); 

       _.For<IDatabase>().Add<Database>().Named("green") 
        .Ctor<string>("connectionString").Is("*green*"); 

       _.Policies.Add<InjectDatabaseByName>(); 
      }); 


      // ImportantService should get the "red" database 
      container.GetInstance<ImportantService>() 
       .DB.As<Database>().ConnectionString.ShouldBe("*red*"); 

      // BigService should get the "green" database 
      container.GetInstance<BigService>() 
       .DB.As<Database>().ConnectionString.ShouldBe("*green*"); 

      // DoubleDatabaseUser gets both 
      var user = container.GetInstance<DoubleDatabaseUser>(); 

      user.Green.As<Database>().ConnectionString.ShouldBe("*green*"); 
      user.Red.As<Database>().ConnectionString.ShouldBe("*red*"); 

     } 
    } 

    public interface IDatabase { } 

    public class Database : IDatabase 
    { 
     public string ConnectionString { get; set; } 

     public Database(string connectionString) 
     { 
      ConnectionString = connectionString; 
     } 

     public override string ToString() 
     { 
      return string.Format("ConnectionString: {0}", ConnectionString); 
     } 
    } 

    public class InjectDatabaseByName : ConfiguredInstancePolicy 
    { 
     protected override void apply(Type pluginType, IConfiguredInstance instance) 
     { 
      instance.Constructor.GetParameters() 
       .Where(x => x.ParameterType == typeof(IDatabase)) 
       .Each(param => 
       { 
         // Using ReferencedInstance here tells StructureMap 
         // to "use the IDatabase by this name" 
         var db = new ReferencedInstance(param.Name); 
        instance.Dependencies.AddForConstructorParameter(param, db); 
       }); 
     } 
    } 

    public class BigService 
    { 
     public BigService(IDatabase green) 
     { 
      DB = green; 
     } 

     public IDatabase DB { get; set; } 
    } 

    public class ImportantService 
    { 
     public ImportantService(IDatabase red) 
     { 
      DB = red; 
     } 

     public IDatabase DB { get; set; } 
    } 

    public class DoubleDatabaseUser 
    { 
     public DoubleDatabaseUser(IDatabase red, IDatabase green) 
     { 
      Red = red; 
      Green = green; 
     } 

     // Watch out for potential conflicts between setters 
     // and ctor params. The easiest thing is to just make 
     // setters private 
     public IDatabase Green { get; private set; } 
     public IDatabase Red { get; private set; } 
    } 
} 

回答

0

我在測試中使用的As<T>()擴展方法是不是FCL的一部分,這就是爲什麼你沒有找到它。如果你正在使用Shouldly,你可以通過ShouldBeOfType<T>()實現同樣的效果,或者在進行比較之前進行正常投射。 Each()擴展名與此相同。