在 StructureMap 中使用策略的示例缺少依赖项
Missing dependencies for an example of using policies in StructureMap
我正在尝试了解 example 2 如何在 StructureMap 中使用策略。我创建了一个小的测试项目(下面的代码)。不幸的是,由于某些原因似乎存在一些依赖性问题,因为 .As<type>
和 .Each
都不起作用。
对于使用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.
我使用 NuGet 安装了 StructureMap 4.2。正如您在下面的代码中看到的,我输入了我能找到的来自 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; }
}
}
我在测试中使用的 As<T>()
扩展方法不是 BCL 的一部分,这就是您找不到它的原因。如果您使用的是 Shouldly,您可以使用 ShouldBeOfType<T>()
产生同样的效果,或者在进行比较之前正常投射它。 Each()
扩展也是如此。
我正在尝试了解 example 2 如何在 StructureMap 中使用策略。我创建了一个小的测试项目(下面的代码)。不幸的是,由于某些原因似乎存在一些依赖性问题,因为 .As<type>
和 .Each
都不起作用。
对于使用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.
我使用 NuGet 安装了 StructureMap 4.2。正如您在下面的代码中看到的,我输入了我能找到的来自 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; }
}
}
我在测试中使用的 As<T>()
扩展方法不是 BCL 的一部分,这就是您找不到它的原因。如果您使用的是 Shouldly,您可以使用 ShouldBeOfType<T>()
产生同样的效果,或者在进行比较之前正常投射它。 Each()
扩展也是如此。