C# structuremap:使用setter注入设置对象的所有属性
我用它作为我的容器。我希望将类的所有依赖项作为依赖项对象传递,而不是每个依赖项传递一个参数C# structuremap:使用setter注入设置对象的所有属性,c#,dependency-injection,structuremap,C#,Dependency Injection,Structuremap,我用它作为我的容器。我希望将类的所有依赖项作为依赖项对象传递,而不是每个依赖项传递一个参数 // Dependencies of Controller class Dependencies { public IUserDatabase UserDatabase { get; set; } public IProductDatabase ProductDatabase { get; set; } // more dependencies ... } class Contr
// Dependencies of Controller
class Dependencies {
public IUserDatabase UserDatabase { get; set; }
public IProductDatabase ProductDatabase { get; set; }
// more dependencies ...
}
class Controller {
Dependencies _d;
Controller(Dependencies dependencies){
this._d = dependencies;
}
public ActionResult Action() {
var user = _this._d.GetUserById(10);
var product = _this._d.GetProductById(20);
// ...
}
}
在通过structuremap构建类的实例时,如何使用setter注入(IUserDatabase
,IProductDatabase
等)自动设置所有依赖项
var container = new Container();
// How to configure this in a generic way?
var dependencies = container.GetInstance<Dependencies>();
此控制器有两个动作。这些操作都没有使用控制器的所有依赖项。此外,通过构造函数注入将依赖项传递给控制器会产生很多噪音
相反,我希望将操作的依赖项作为参数直接传递给该操作。我们有自己的路由,可以很容易地支持这一点
class Action1Dependencies {
public IUserDatabase UserDatabase {get; set;}
public IProductDatabase ProductDatabase {get; set;}
}
class Action2Dependencies {
public IRatingDatabase RatingDatabase {get; set;}
public ICommentsDatabase CommentsDatabase {get; set;}
}
class MyController {
public static ActionResult Action1(Action1Dependencies d){
var user = d.UserDatabase.GetById(10);
var product = d.ProductDatabase.GetById(20);
}
public static ActionResult Action2(Action2Dependencies d) {
var ratings = d.RatingDatabase.GetById(20);
var comments = d.CommentsDatabase.GetById(20);
}
}
因此,我想做一个调用,比如var dependencies=container.GetInstance,上面的代码也可能变成
class MyController {
public static ActionResult Action1((IUserDatabase UserDatabase, IProductDatabase ProductDatabase) d){
var user = d.UserDatabase.GetById(10);
var product = d.ProductDatabase.GetById(20);
}
public static ActionResult Action2((IRatingDatabase RatingDatabase, ICommentsDatabase CommentsDatabase) d) {
var ratings = d.RatingDatabase.GetById(20);
var comments = d.CommentsDatabase.GetById(20);
}
}
正如@haim770所建议的那样,您必须在依赖项
类中创建一个需要所有依赖项的构造函数
但在这种情况下,您只需将问题从控制器转移到依赖项类
// Dependencies of Controller
class Dependencies {
public IUserDatabase UserDatabase { get; set; }
public IProductDatabase ProductDatabase { get; set; }
// more dependencies ...
public Dependencies(IUserDatabase userDatabase, IProductDatabase productDatabase)
{
UserDatabase = userDatabase;
ProductDatabase = productDatabase;
}
}
然后,您的容器代码就可以工作了
var container = new Container();
var dependencies = container.GetInstance<Dependencies>();
var container=newcontainer();
var dependencies=container.GetInstance();
这可以通过Setter注入策略实现,请参阅
您还可以以更一般的方式定义策略,例如,为依赖项对象使用标记接口
interface IDependencies {}
property => typeof(IDependencies).IsAssignableFrom(property.DeclaringType)
你为什么要这样做?这是一个坏主意,因为如果您更改依赖项,您有多个地方要编辑,这样做没有任何好处……请修改依赖项类,使其具有一个构造函数,该构造函数期望所有内部依赖项和StructureMap随后将为您处理注入。另外,如果您这样做是因为您有许多依赖项,那么您可能会有兴趣检查,尽管在一个后面抽象一组依赖项是很好的,但我认为您缺少一个抽象。为了简化操作
,更常见的做法是将这些依赖项及其逻辑移动到业务层,并让此业务组件以适合控制器的方式返回数据。这样控制器中就没有什么行为了。请查看我问题中的编辑。
var container = new Container(x => {
x.Policies.SetAllProperties(
policy => policy.Matching(
property => property.DeclaringType == typeof(Dependencies)
);
});
interface IDependencies {}
property => typeof(IDependencies).IsAssignableFrom(property.DeclaringType)