如何使用 Autofac 将控制器的 ModelState 传递给我的服务构造函数? [英] How to pass controller's ModelState to my service constructor with Autofac?

查看:18
本文介绍了如何使用 Autofac 将控制器的 ModelState 传递给我的服务构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 ModelStateDictionary 上有一个包装器,我的所有服务都接受它.是否可以将 autofac 配置为将控制器 ModelStateDictionary 注入到包装器的构造函数中,然后将其注入到服务构造函数中?

I have a wrapper on ModelStateDictionary which all my services accept. Is it possible to configure the autofac to inject the controller ModelStateDictionary into the constructor of the wrapper and then inject it into service constructor?

//code
public class ModelValidation : IModelValidation { 
public ModelValidation(ModelStateDictionary msd){...}
..
..
}

public class CustomerService{
public CustomerService(IModelValidation mv){...}
..
}

谢谢

推荐答案

根据您的评论,我在此修改我的答案 :)

Based on your comments I hereby revise my answer :)

ModelStateDictionary 显然不是应该由容器解析的服务,而是应该在实例化时提供的数据.我们可以从 ModelState 由每个 Controller 实例拥有,因此在解析时"对容器不可用这一事实判断.

ModelStateDictionary is clearly not a service that should be resolved by the container, but rather data that should be provided at instantiation time. We can tell that from the fact that ModelState is owned by each Controller instance and is thus not available to the container at "resolve time".

此外,每个ModelValidation 实例都将绑定到一个ModelStateDictionary 实例,因此也被视为数据.

Furthermore, each ModelValidation instance will be bound to a ModelStateDictionary instance and is thus also to be considered as data.

在 Autofac 中,当数据必须传递给构造函数时(除了其他依赖项之外,还可以选择),我们必须使用工厂委托.这些委托将处理传递给构造函数的依赖项和数据.Autofac 的好处是这些委托可以自动生成.

In Autofac, when data must be passed to constructors (optionally in addition to other dependencies), we must use factory delegates. These delegates will handle dependency and data passing to the constructor. The sweet thing with Autofac is that these delegates can be autogenerated.

我提出以下解决方案:

由于 ModelValidation 和 CustomerService 的构造函数中都需要数据,所以我们需要两个工厂委托(注意:参数名称必须与其对应的构造函数中的名称匹配):

Since both ModelValidation and CustomerService requires data in their constructors, we need two factory delegates (note: the parameter names must match the names in their corresponding constructor):

public delegate IModelValidation ModelValidationFactory(ModelStateDictionary msd);
public delegate CustomerService CustomerServiceFactory(ModelStateDictionary msd);

由于您的控制器不应该知道这些委托来自哪里,因此它们应该作为依赖项传递给控制器​​构造函数:

Since your controllers shouldn't know where these delegates comes from they should be passed to the controller constructor as dependencies:

public class EditCustomerController : Controller
{
    private readonly CustomerService _customerService;

    public EditCustomerController(CustomerServiceFactory customerServiceFactory
        /*, ...any other dependencies required by the controller */
          )
    {
        _customerService = customerServiceFactory(this.ModelState);
    }

}

CustomerService 应该有一个与此类似的构造函数(可选地在 ServiceBase 类中处理其中的一些):

The CustomerService should have a constructor similar to this (optionally handle some of this in a ServiceBase class):

public class CustomerService
{
    private readonly IModelValidation _modelValidation;

    public CustomerService(ModelStateDictionary msd,
              ModelValidationFactory modelValidationFactory)
    {
        _modelValidation = modelValidationFactory(msd);
    }

为了实现这一点,我们需要像这样构建我们的容器:

To make this happen we need to build our container like this:

var builder = new ContainerBuilder();

builder.Register<ModelValidation>().As<IModelValidation>().FactoryScoped();
builder.Register<CustomerService>().FactoryScoped();

builder.RegisterGeneratedFactory<ModelValidationFactory>();
builder.RegisterGeneratedFactory<CustomerServiceFactory>();

builder.Register<EditCustomerController>().FactoryScoped();

因此,当控制器被解析时(例如,当使用 MvcIntegration 模块),工厂委托将被注入到控制器和服务中.

So, when the controller is resolved (eg when using the MvcIntegration module), the factory delegates will be injected into the controllers and services.

更新:为了进一步减少所需的代码,您可以将 CustomerServiceFactory 替换为我所描述的通用工厂委托 此处.

Update: to cut down on required code even more, you could replace CustomerServiceFactory with a generic factory delegate like I've described here.

这篇关于如何使用 Autofac 将控制器的 ModelState 传递给我的服务构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆