Измените значение свойства ViewModel с помощью плагина в nopCommerce
Я работаю над nopCommerce v3.90. У меня есть требование к плагину, который обновлял бы первоначальную цену продукта в некотором процентном соотношении на основе настроек, выполненных в разделе настроек плагина, без изменения существующей структуры модели nopCommerce.
Следовательно, каждый раз, когда отображается цена продукта, нужно видеть новую обновленную цену (основанную на действии, выполняемом в плагине) вместо цены из базы данных.
Кто-нибудь может мне с этим помочь?
Существующий класс Model в nopCommerce
public partial class ProductPriceModel : BaseNopModel
{
//block of statements
public string Price { get; set; } //the property whose value need to be changed from plugin
//block of statements
}
1 ответ
В 3.9 варианты, которые я знаю,
- Override
PrepareProductPriceModel
метод вIProductModelFactory
класс и предоставить собственную реализацию, используя переопределение зависимостей - Реализовать
ActionFilter
настроитьProductPriceModel
прежде чем он привыкнет в представлении.
В 4.0 это очень просто. Вам нужно только подписаться на ModelPreparedEvent
а затем настроить ProductPriceModel
,
Override IProductModelFactory
public class CustomProductModelFactory : ProductModelFactory
{
// ctor ....
protected override ProductDetailsModel.ProductPriceModel PrepareProductPriceModel(Product product)
{
// your own logic to prepare price model
}
}
В вашем плагине регистратор зависимостей
builder.RegisterType<CustomProductModelFactory>()
.As<IProductModelFactory>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope();
Воплощать в жизнь ActionFilter
public class PriceInterceptor : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null) throw new ArgumentNullException(nameof(filterContext));
if (filterContext.HttpContext?.Request == null) return;
if (filterContext.Controller is Controller controller)
{
if (controller.ViewData.Model is ProductDetailsModel model)
{
// your own logic to prepare price model
}
}
}
}
И чтобы динамически обеспечить ваш ActionFilter
public class PriceInterceptorFilterProvider : IFilterProvider
{
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
return new[] { new Filter(new PriceInterceptor(), FilterScope.Action, null) };
}
}
В вашем плагине регистратор зависимостей
builder.RegisterType<PriceInterceptorFilterProvider>()
.As<IFilterProvider>();
Подписываться на ModelPreparedEvent<ProductDetailsModel>
(nopCommerce 4.0)
public class PriceInterceptor : IConsumer<ModelPreparedEvent<ProductDetailsModel>>
{
public void HandleEvent(ModelPreparedEvent<ProductDetailsModel> eventMessage)
{
// your own logic to prepare price model
}
}