Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# structuremap:使用setter注入设置对象的所有属性_C#_Dependency Injection_Structuremap - Fatal编程技术网

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)