Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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# 使用IoC解析动作方法中的模型对象_C#_Asp.net Mvc_Dependency Injection_Inversion Of Control - Fatal编程技术网

C# 使用IoC解析动作方法中的模型对象

C# 使用IoC解析动作方法中的模型对象,c#,asp.net-mvc,dependency-injection,inversion-of-control,C#,Asp.net Mvc,Dependency Injection,Inversion Of Control,我在Asp.NETMVC3中使用IoC容器进行依赖注入,在我开始在控制器中编写操作方法之前,一切似乎都很完美。在动作方法中创建实体/模型对象的最佳方式是什么?有时,模型是从特定的存储库或服务中检索的,这些存储库或服务通过构造函数注入控制器,但系统中的许多其他模型对象并非如此 您不使用DI容器来解析操作参数。这就是a在ASP.NET MVC中的意图。顺便说一下,您的操作应该将任何域模型作为参数=>它们应该只接受视图模型。视图模型是为满足给定视图的要求而专门定义的类 因此,对于某些特定情况,您可以编

我在Asp.NETMVC3中使用IoC容器进行依赖注入,在我开始在控制器中编写操作方法之前,一切似乎都很完美。在动作方法中创建实体/模型对象的最佳方式是什么?有时,模型是从特定的存储库或服务中检索的,这些存储库或服务通过构造函数注入控制器,但系统中的许多其他模型对象并非如此

您不使用DI容器来解析操作参数。这就是a在ASP.NET MVC中的意图。顺便说一下,您的操作应该将任何域模型作为参数=>它们应该只接受视图模型。视图模型是为满足给定视图的要求而专门定义的类


因此,对于某些特定情况,您可以编写自定义模型绑定器,该绑定器将负责动作参数的实例化和绑定。就模型绑定器本身的实例化而言,在ASP.NET MVC 3中,您可以使用一个可用于使用您选择的DI框架将依赖项注入此模型绑定器的实例。

最好使用IOC容器来创建组件;但它不应用于创建模型对象。例如,这很好:

模型对象本身不应该具有任何依赖关系,因此不需要从IOC容器中解析它。这同样适用于视图模型:

public ActionResult Show(int userId)
{
    var user = _repository.Load<User>(userId);

    var model = new ShowUserModel(user);
    return View(model);
}
public ActionResult Show(int-userId)
{
var user=\u repository.Load(userId);
var模型=新的ShowUserModel(用户);
返回视图(模型);
}
创建后,模型/视图模型应该是有效的只读的,因此它需要的任何信息都应该通过控制器传递进来——它不应该接受注入的依赖项

如果您确实需要在操作中动态创建组件,您可以这样做:

class HomeController : Controller
{
     readonly Func<IFooService> _fooServiceFactory;

     public HomeController(Func<IFooService> fooServiceFactory)
     {
         _fooServiceFactory = fooServiceFactory;
     }

     public ActionResult SomeAction() 
     {
         var service = _fooServiceFactory(); // Resolves IFooService dynamically
         service.DoStuff();
     }
}
类HomeController:控制器
{
只读功能工厂;
公共家庭控制器(Func fooServiceFactory)
{
_fooServiceFactory=fooServiceFactory;
}
公共行动结果某些行动()
{
var service=\u fooServiceFactory();//动态解析IFooService
service.DoStuff();
}
}

任何像样的IOC容器都应该能够处理
Func
注入

你能告诉我们更多的细节吗?如果一些模型对象不是来自存储库或服务,那么它们来自哪里?如果要创建新的模型对象,可以将模型工厂/生成器作为依赖项插入。实际上,有一个控制器包含多个步骤,大多数(如果不是所有)操作都会使用不同的模型生成不同的视图,并设置为“视图模型”。HtmlHelper需要一个空对象集作为模型,以使用其扩展方法来显示表单以接受数据,并且此视图的viewmodel具有特定实体类型的某些属性,例如
SiteSettings
class。我不确定如何从动作方法中解决ViewModel及其依赖关系。我认为您最初提出的问题与您可能想提出的问题不同。这个问题是关于如何使用IOC容器解析动作中的对象。您真正的问题听起来可能是“如何在ASP.NET MVC中创建向导?”,我认为正确的答案不包括在action方法中使用IOC容器。如果你问一个新问题,你可能会得到一个更好的解决办法。@PaulStovell事实上,我和IoC在刚开始的时候有点问题。我想要的是,有一个简单的Action方法,它只创建一个viewmodel,其中有一个Settings类作为属性。我想,我会将这些视图模型和其他实体(如
Settings
)与其他实体一起注册到IoC,IoC会为我创建它,我就是这么做的。从下面的答案中,我认为我做错了。因此,这些视图模型和仅由控制器的一个或两个方法使用的简单支持类可以使用
new
直接创建?在创建向导时,我不是在寻求帮助!模型或视图模型,我不是在谈论发布的数据或参数,因此,我们将如何生成需要传递给视图的数据,比如从基本CRUD控制器的
Create
action方法。那么,视图模型可以直接创建吗?@Threecoins,我不确定我是否理解你的要求。传递给视图的数据以视图模型的形式存在。视图模型是一个类,您可以定义并包含此视图所需的信息。然后,控制器操作将查询存储库以获取域模型,然后将此域模型映射到视图模型,并将视图模型传递给视图。也许你可以展示一些代码来更好地解释你的问题?@DarinDimitrov如果你能用Autofac实现这样一个模型绑定器,那就太棒了。为什么不使用普通的构造函数注入呢。并不是说我反对Func。我同意,理想情况下你会的。但是问题的标题是“使用IoC在action方法中解析模型对象”(尽管我怀疑有更好的方法来实现真正的目标)。现实世界中的情况可能是,您有六个操作,其中只有一个需要
iFoosService
,而创建
iFoosService
的成本很高。在这种情况下,我们可以将
IFooService
的解析推迟到操作,这样就不会对不需要它的操作进行解析。也就是说,这可能意味着
iFoosService
首先存在设计问题:)或者
IWhateverController
存在设计问题——您可能希望围绕昂贵的服务构建控制器。
class HomeController : Controller
{
     readonly Func<IFooService> _fooServiceFactory;

     public HomeController(Func<IFooService> fooServiceFactory)
     {
         _fooServiceFactory = fooServiceFactory;
     }

     public ActionResult SomeAction() 
     {
         var service = _fooServiceFactory(); // Resolves IFooService dynamically
         service.DoStuff();
     }
}