Измените значение свойства 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
    }
}
Другие вопросы по тегам