//code public class ModelValidation : IModelValidation { public ModelValidation(ModelStateDictionary msd){...} .. .. } public class CustomerService{ public CustomerService(IModelValidation mv){...} .. }
谢谢
解决方法
ModelStateDictionary显然不是应该由容器解析的服务,而是应该在实例化时提供的数据.我们可以告诉我,ModelState由每个Controller实例拥有,因此在“解析时间”不可用于容器.
此外,每个ModelValidation实例都将绑定到ModelStateDictionary实例,因此也被视为数据.
在Autofac中,当必须将数据传递给构造函数时(可选地除了其他依赖项之外),我们必须使用工厂委托.这些委托将处理传递给构造函数的依赖项和数据. Autofac的好处在于这些代表可以自动生成.
我提出以下解决方案:
由于ModelValidation和CustomerService都需要构造函数中的数据,因此我们需要两个工厂委托(注意:参数名称必须与其相应构造函数中的名称匹配):
public delegate IModelValidation ModelValidationFactory(ModelStateDictionary msd); public delegate CustomerService CustomerServiceFactory(ModelStateDictionary msd);
由于您的控制器不应该知道这些委托来自何处,因此它们应该作为依赖项传递给控制器构造函数:
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类中处理其中的一些):
public class CustomerService { private readonly IModelValidation _modelValidation; public CustomerService(ModelStateDictionary msd,ModelValidationFactory modelValidationFactory) { _modelValidation = modelValidationFactory(msd); }
为了实现这一点,我们需要像这样构建我们的容器:
var builder = new ContainerBuilder(); builder.Register<ModelValidation>().As<IModelValidation>().FactoryScoped(); builder.Register<CustomerService>().FactoryScoped(); builder.RegisterGeneratedFactory<ModelValidationFactory>(); builder.RegisterGeneratedFactory<CustomerServiceFactory>(); builder.Register<EditCustomerController>().FactoryScoped();
因此,当控制器被解析时(例如,当使用the MvcIntegration module时),工厂代表将被注入控制器和服务.
更新:为了进一步减少所需的代码,您可以将CustomerServiceFactory替换为通用的工厂委托,就像我描述的那样here.
原文地址:https://www.jb51.cc/aspnet/251280.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。