[英]Is there a way to resolve a dependency-injected service into an ASPNET Core MVC model with only a default constructor?
My .NET 6 AS.NET MVC application has the usual controller, model and view scenario, with a separate service layer/interface for getting and saving data.我的 .NET 6 AS.NET MVC 应用程序具有通常的 controller、model 和视图场景,具有用于获取和保存数据的单独服务层/接口。 The service is injected into the controller via it's constructor, which gets the data and via the service.
该服务通过其构造函数注入到 controller 中,该构造函数通过服务获取数据。 The service is also injected into the model's constructor, but because the model also requires a constructor with no parameters (for model binding when the form in the view is posted), so the service reference within the model is null, which causes problems when a "computed" property of the model is accessed which relies on a call to the service.
该服务也被注入到模型的构造函数中,但是因为model也需要一个无参数的构造函数(用于model在视图中的表单发布时绑定),所以model内的服务引用是null,这会导致问题访问 model 的“计算”属性依赖于对服务的调用。
I'm aware that I can access the service instance when validating the model (via IServiceProvider being implemented by the ValidationContext argument to my model's implementation of IValidatableObject.Validate) but how can I access an IServiceProvider elsewhere in a model that's been constructed using the default constructor?我知道我可以在验证 model 时访问服务实例(通过我的模型的 IValidatableObject.Validate 实现的 ValidationContext 参数实现的 IServiceProvider)但是我如何访问使用默认构造的 model 中其他地方的 IServiceProvider构造函数?
I've thought about encapsulating an IServiceProvider within a global/singleton class but suspect that would cause issues and doesn't seem at all elegant.我考虑过将 IServiceProvider 封装在全局/单例 class 中,但怀疑这会导致问题并且看起来一点也不优雅。
I presume you are trying to do something like this:我假设你正在尝试做这样的事情:
class MyModel
{
readonly MyService _myService;
public MyModel(MyService myService)
{
_myService = myService;
}
public string Prop1 { get; set; }
public string ComputedProp => _myService.Compute(Prop1);
}
A model for posting to a controller should really be a pure DTO (Data Transfer Object) and not include any behaviour such as this.发送到 controller 的 model 实际上应该是一个纯 DTO(数据传输对象),不包括任何此类行为。
I would echo WiseGuy's suggestion and implement as follows:我会回应 WiseGuy 的建议并按如下方式实施:
class MyModel
{
public string Prop1 { get; set; }
// Initialize to avoid model binding validation error
// when null
public string Prop2 { get; set; } = string.Empty;
}
class MyController
{
readonly MyService _myService;
public MyController(MyService myService)
{
_myService = myService;
}
public async Task PostAsync(MyModel myModel)
{
myModel.Prop2 = _myService.Compute(myModel.Prop1);
// Rest of method
}
}
I would go further to say that a computed value does not belong on the DTO at all.我会 go 进一步说计算值根本不属于 DTO。 Ideally the model used to post to your controller is not the same class as is used deeper in your application and the model should be transformed in the controller:
理想情况下,用于发布到您的 controller 的 model 与在您的应用程序中更深入使用的 class 不同,model 应该在 controller 中进行转换:
class MyModel
{
public string Prop1 { get; set; }
}
class MyEntity
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
class MyController
{
readonly MyService _myService;
public MyController(MyService myService)
{
_myService = myService;
}
public async Task PostAsync(MyModel myModel)
{
MyEntity myEntity = new MyEntity()
{
Prop1 = myModel.Prop1,
Prop2 = _myService.Compute(myModel.Prop1);
}
// Rest of method - using myEntity, not myModel
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.