Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Frans Lammers 57 posts 400 karma points c-trib
    Jan 04, 2023 @ 16:14
    Frans Lammers
    0

    Vendr - custom productadapter not working

    Hallo,

    We are working on a project using Vendr 3.0.4 in Umbraco 10.2.1

    In this project the products are no Umbraco nodes, but separately stored in the database. We have made a custom productadapter to pass the products to Vendr, but when we try to add a product to the cart the next error appears:

        ArgumentNullException: Value cannot be null. (Parameter 'productSnapshot')
    Vendr.Core.Models.Order.AddProduct(IProductSnapshot productSnapshot, decimal qty, IDictionary<string, string> properties, string bundleId, string parentBundleId, IEnumerable<string> uniquenessPropertyAliases)
    Vendr.Extensions.OrderExtensions.AddProduct(Order order, string productReference, string productVariantReference, decimal qty)
    MyProject.Core.Controllers.CartSurfaceController.AddToCart(AddToCartDto model) in CartSurfaceController.cs
    

    So perhaps there is something wrong with my productadapter, but I can not find it.

    In my startup.cs I added:

    .AddVendr(vendrBuilder => { vendrBuilder.AddMyDependancies(); })
    

    which points to my VenrBuilderExtension:

    public static IVendrBuilder AddMyDependancies(this IVendrBuilder builder)
        {
            // Replacing the default Product Adapter implementation
            builder.Services.AddUnique<IProductAdapter, CustomProductAdapter>();
    
            // Return the builder to continue the chain
            return builder;
        }
    

    In my CustomProductAdapter I have implemented the methods for GetProductSnapshot and TryGetProductReference, but in the debugger these methods are not hit when I try to add a product to the cart.

    It seems to me that the CustomProductAdapter is not being used. What can I do about it?

    thanks,

    Frans

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jan 05, 2023 @ 09:18
    Matt Brailsford
    0

    Hi Frans,

    Where within the ConfigureServices method, in the list of Add extensions are you calling AddVendr? When using AddVendr this needs to be before the AddComposers call.

    Everything else seems like it should be ok to me 🤔

  • Frans Lammers 57 posts 400 karma points c-trib
    Jan 05, 2023 @ 09:30
    Frans Lammers
    0

    Hi Matt,

    This is my ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
            {
                services.AddUmbraco(_env, _config)
                    .AddBackOffice()
                    .AddWebsite()
                    .AddComposers()
                    .AddVendr(vendrBuilder => { vendrBuilder.AddMyDependancies(); })
                    .AddSection<CustomSection>()
                    .AddCustomMigration()
                    .Build();
            }
    

    First I had put AddVendr before the AddComposers and then I got an errormessage like this:

    An error occurred while starting the application.
    AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Vendr.Core.Services.IProductPriceFreezerService Lifetime: Singleton ImplementationType: Vendr.Core.Services.ProductPriceFreezerService': Cannot consume scoped service 'MyProject.Core.Services.IProductService' from singleton 'Vendr.Core.Adapters.IProductAdapter'.) 
    

    I guessed this is because I use my own ProductService inside the ProductAdapter. When I put AddVendr after the AddComposers the compilation went well, but the ProductAdapter is not called.

    So I guess I have to add all my services after calling addVendr. Is this right?

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jan 05, 2023 @ 10:04
    Matt Brailsford
    100

    So AddVendr should go before AddComposers. The only reason this "fixes" your error is because your code to add your adapter isn't run, because Vendr has a composer that automatically calls AddVendr if it hasn't already been called yet, and then when you call AddVendr yourself, it gets canceled because Vendr has already been added.

    So, move your AddVendr call to before AddComposers and then look to resolve your dependency issue.

    As the depedency error states, your custom IProductService is registered as a scoped dependency, which can't be access directly within the Vendr ProductPriceFreezerService because this is registered as a singleton.

    You'll either need to

    1. Register your product service as a singleton
    2. Implement an Accessor pattern for your product service
    3. Don't resolve it as a constructor dependency and instead wrap your code that accesses it within scope and then use that scope to resolve the dependency.

    This is standard .NET dependency injection so not specifically a Vendr issue. Do a search for resolving scoped services within singletons.

  • Novaspark 3 posts 23 karma points
    Jul 17, 2023 @ 14:52
    Novaspark
    0

    Hi, Can I suggest that the example in the documentation is updated to reflect this please? https://vendr.net/docs/core/3.0.0/key-concepts/dependency-injection/

    Prior to v3 when dependencies were set against IUmbracoBuilder they could be set after the AddComposers() call but on upgrading to v3 and setting using IVendrBuilder they don't fire unless they're moved above AddComposers().

    Having read the above post I now understand why but that's not much consolation for the wasted hours... :(

    Thanks in advance

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jul 17, 2023 @ 15:11
    Matt Brailsford
    0

    Hmm, I think something does probably need updating on that page, but I need to decide what.

    That page is talking about the concept of dependency injection so if just thinking from that context, it should be fine to add dependencies after composers. The problem here really is that we do show examples using Vendr resources (thats because those examples were written before the introduction of IVendrBuilder) so in that case, those should be more general examples.

    If you look at the IVendrBuilder docs https://vendr.net/docs/core/3.0.0/key-concepts/vendr-builder/ the examples do show the AddVendr call as being before the AddComposers.

    It's tricky as the docs are really just trying to introduce concepts which further articles then add to so in a sense, the DI docs set the understanding of DI, the IVendrBuilder docs set the understanding of the Vendr Builder API which uses DI, and then other Vendr stuff uses Vendr Builder as the way to register those.

  • Novaspark 3 posts 23 karma points
    Jul 17, 2023 @ 15:27
    Novaspark
    0

    Yeah, good point. I think I got caught because I was upgrading and the release notes just mentioned IVendrBuilder and I assumed it was a direct replacement for my IUmbracoBuilder Vendr-related dependencies.

    Your comment about the Composer automatically calling AddVendr would be good to stick in the docs somewhere too.

    Cheers

  • Frans Lammers 57 posts 400 karma points c-trib
    Jan 05, 2023 @ 10:10
    Frans Lammers
    0

    Hi Matt, I had just seen that the error really lies in the scoped/singleton registering, so I will look into this.

    Thanks!

    Frans

Please Sign in or register to post replies

Write your reply to:

Draft