Copied to clipboard

Flag this post as spam?

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


  • ianhoughton 281 posts 605 karma points c-trib
    May 16, 2019 @ 07:34
    ianhoughton
    0

    Autofac error

    I've incorporated the starter kit product page into our site, but its falling over on this line:

    List<VariantPublishedContent> variants = TC.GetVariants(storeId, Model, true).ToList();
    

    The error is:

    The requested service 'TeaCommerce.Umbraco.Configuration.Variants.Services.IVariantService`2[[Website.Core.Models.DocumentTypes.ProductDetailPage, Website.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[TeaCommerce.Umbraco.Configuration.Variants.Models.VariantPublishedContent, TeaCommerce.Umbraco.Configuration, Version=3.3.6977.16237, Culture=neutral, PublicKeyToken=null]]' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

    We're using Autofac for our DI and this is how its setup:

    public static void RegisterDependencies()
        {
            var builder = new ContainerBuilder();
    
            // register all controllers found in your assembly
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
    
            // register controllers from other Plugin DLL's otherwise they might break the back office
            RegisterCustomApiControllers(builder);
    
            // register Umbraco MVC + web API controllers used by the admin site
            builder.RegisterControllers(typeof(UmbracoApplication).Assembly);
            builder.RegisterApiControllers(typeof(UmbracoApplication).Assembly);
    
            // Register custom services etc.
            builder.Register(c => new EmailService()).As<IEmailService>().InstancePerLifetimeScope();
    
            var container = builder.Build();
    
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            var resolver = new AutofacWebApiDependencyResolver(container);
            GlobalConfiguration.Configuration.DependencyResolver = resolver;
        }
    

    These are the DLL's in the bin folder:

    enter image description here

    Any ideas what I'm doing wrong??

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    May 16, 2019 @ 07:55
    Matt Brailsford
    0

    Hi Ian,

    TC uses AutoFac for it's DI container also so I'm guessing you've likely replaced the builder instance thus removed all of TC's dependency registrations.

    This is the line in TCForUmbraco that triggers all of TC's DI configuration:

    https://github.com/TeaCommerce/Tea-Commerce-for-Umbraco/blob/master/Source/TeaCommerce.Umbraco.Configuration/ApplicationStartup.cs#L22

    I'd probably suggest calling this and adding in a reference to your DLL and then use AutoFac Modules to define your custom registrations (as this is what the TC DependencyContainer looks for).

    Matt

  • ianhoughton 281 posts 605 karma points c-trib
    May 16, 2019 @ 09:06
    ianhoughton
    0

    So replace my current DI setup with:

    DependencyContainer.Configure(Assembly.Load("Website.Core"));
    

    and create a module like:

    public class ServicesConfig : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.MustNotBeNull<ContainerBuilder>(nameof(builder));
            builder.RegisterType<EmailService>().As<IEmailService>().PreserveExistingDefaults<EmailService, ConcreteReflectionActivatorData, SingleRegistrationStyle>().InstancePerLifetimeScope();            
        }
    }
    

    how do I register that Module outside of the TeaCommerce code?

    I tried adding this code to my ApplicationStarted method:

    ModuleRegistrationExtensions.RegisterAssemblyModules(builder, new Assembly[1]
            {
                Assembly.Load("Website.Core")
            });
    

    but I can't get access to "builder"

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    May 16, 2019 @ 09:16
    Matt Brailsford
    0

    DependencyContainer.Configure should do the loading of the modules for you. Inside each module you have access to the builder to register your types.

    DependencyContainer.Configure should be called from within a ApplicationEventHandler much like the one in the TC4Umbraco.

    When you call DependencyContainer.Configure, be sure to also include the TC4Umbraco assembly's as well.

    Full disclosure, I'm not overly familiar with Autofac so I have asked Run from TeaSolutions to see if he wouldn't mind coming to have a look at this and just double check what I'm suggesting is correct. Hopefully he will be able to confirm.

  • Rune Grønkjær 1372 posts 3103 karma points
    May 16, 2019 @ 10:49
    Rune Grønkjær
    0

    Hm. That's a good question. So as I read it Ian, you are doing your own autofac and that might be messing with the TC autofac. And yes, it does look like you might be overwriting the something important, although TC does it a little different.

    Have you first of all confirmed that it's your own code that messes with TC? Maybe have a look at how TC registers it's types: https://github.com/TeaCommerce/Tea-Commerce-for-Umbraco/blob/770705bdea8f20fd9e146c27724c9a830454c8e0/Source/TeaCommerce.Umbraco.Configuration/AutofacModules/InformationExtractorsConfig.cs You might be able to do it the same way.

    /Rune

  • ianhoughton 281 posts 605 karma points c-trib
    May 25, 2019 @ 09:56
    ianhoughton
    0

    I've been playing around with this issue again this morning, and have found it's related to ModelsBuilder.

    If I render my Product Page with this code:

    @inherits UmbracoViewPage<ProductDetailPage>
    
    long storeId = long.Parse(Model.GetPropertyValue<string>("store", true));
    
    List<VariantPublishedContent> variants = TC.GetVariants(storeId, Model, true).ToList();
    

    it throws the error at the start of this thread.

    If I render my Product Page with this code:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    
    long storeId = long.Parse(Model.Content.GetPropertyValue<string>("store", true));
    
    List<VariantPublishedContent> variants = TC.GetVariants(storeId, Model.Content, true).ToList();
    

    Modelsbuilder is setup like this:

    <add key="Umbraco.ModelsBuilder.Enable" value="true" />
    <add key="Umbraco.ModelsBuilder.ModelsMode" value="AppData" />
    <add key="Umbraco.ModelsBuilder.ModelsDirectory" value="~/../xxxxx.Core/Models/DocumentTypes" />
    <add key="Umbraco.ModelsBuilder.AcceptUnsafeModelsDirectory" value="True" />
    <add key="Umbraco.ModelsBuilder.ModelsNamespace" value="xxxxx.Core.Models.DocumentTypes" />
    <add key="Umbraco.ModelsBuilder.LanguageVersion" value="CSharp6" />
    
  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    May 27, 2019 @ 14:37
    Matt Brailsford
    0

    Hey Ian,

    Hmm, that's pretty interesting.

    Is this just a basic setup so far? or is it client specific? Just wondering if you'd be able to send me a copy of the site with DB so I can review it and debug into it?

  • Matthew Wise 271 posts 1373 karma points MVP 5x c-trib
    May 27, 2019 @ 15:58
    Matthew Wise
    1

    Seen this issue with models builder as well.

    If you cast model to IPublishedContent it works. As that is what is registered by Tea, why it doesn't revert the model to the interface I have no idea

    Matt

Please Sign in or register to post replies

Write your reply to:

Draft