有没有办法用DI做到这一点?我试过IScopedInstance<Controller>
,但这给了我null。围绕aspnet的源代码,但没有获胜。有什么想法吗?
我有一个接受不同IPaymentMethod
的控制器。 IPaymentMethod
可以是可以呈现视图的ViewComponent
。如果IPaymentMethod
是ViewComponent
,我希望它在帖子后面使用MVC的内置模型绑定。
public class XController : Controller
{
// ctor, props, ...
public IActionResult Checkout()
{
return View(new Model
{
PaymentMethodId = 1,
PaymentMethodType = typeof(MyPaymentMethod) // The razor file will use this type to render it as a ViewComponent
});
}
[HttpPost]
public IActionResult Checkout(Model model)
{
var paymentMethod = _paymentService.GetPaymentMethodById(model.PaymentMethodId);
paymentMethod.ProcessPayment();
// ..
}
}
这是我需要注入控制器的地方。我想利用内置的MVC验证和模型绑定。
public class MyPaymentMethod : IPaymentMethod
{
private Controller _currentController;
public MyPaymentMethod(IScopedInstance<Controller> controller)
{
_currentController = controller.Value;
}
public void ProcessPayment()
{
var model = new PaymentModel();
_currentController.TryUpdateModel(model, typeof(PaymentModel), null);
if (!_currentController.ModelState.IsValid)
{
return; // or exception
}
// Process Payment using model
}
public Task<IViewComponentResult> InvokeAsync()
{
// returns View
}
}
public interface IPaymentMethod
{
void ProcessPayment();
}
答案 0 :(得分:0)
这不再适用于beta7
在撰写本文时(beta6
),这可能不受支持,并且有充分的理由:ASP.NET 5中的控制器不需要从Controller
类继承。但是,我已经找到了一种方法,可以使用ActionFilters
。
public class ScopeControllerActionFilterAttribute : ActionFilterAttribute
{
private readonly IScopedInstance<Controller> _controller;
public ScopeControllerActionFilterAttribute(IScopedInstance<Controller> controller)
{
_controller = controller;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (_controller.Value == null)
{
_controller.Value = context.Controller as Controller;
}
}
}
请注意,根据http请求生命周期的阶段,Value
的{{1}}可能仍为空。
答案 1 :(得分:0)
由于ProcessPayment
方法中需要模型实例,为什么不简单地将其作为参数传递?
[HttpPost]
public IActionResult Checkout(PaymentModel model)
{
var paymentMethod = _paymentService.GetPaymentMethodById(model.PaymentMethodId);
if (!ModelState.IsValid)
{
return; // or exception
}
paymentMethod.ProcessPayment(model);
// ..
}
public void ProcessPayment(PaymentModel model)
{
// Process Payment using model
}
您的服务承担了属于控制器的职责 - 即检查ModelState.IsValid
。
public interface IPaymentMethod
{
void ProcessPayment(PaymentModel model);
}
您可能还希望仅传递付款模式中所需的属性,或者您可能希望建立IPaymentModel
界面以将您的模型与PaymentService
分离。在这种情况下,您的IPaymentModel
会进入共享层。
public interface IPaymentMethod
{
void ProcessPayment(IPaymentModel model);
}