Module takes priority over theme?

Topics: Writing modules, Writing themes
Jun 24, 2013 at 1:55 PM
Hello!

I have a module with the following in the ResourceManifest.cs

manifest.DefineScript("Script").SetUrl("Script.js").SetDependencies("jQuery", "jQuery.validate", "jQuery.validate.unobtrusive");

And then a theme with this

manifest.DefineScript("Script").SetUrl("Script.js");


Now, when I include the Script in my layout file, the one from the module is used instead of the one in the theme. Why is this? Shouldn't the theme script file take priority, just like my styles do?

This problem messes up a few things for me :(
I read about a similar problem and that it was an old bug, but I'm currently on 1.6.1 and it's not working.

Am I doing something wrong?

Help appreciated, thanks in advance :-)
Developer
Jun 24, 2013 at 3:42 PM
I'm not sure how this should work but probably it should what you expect. However to override scripts from your theme you don't need to re-define it: just place a Script.js there too and it will be used instead the one in the module.
Jun 24, 2013 at 3:51 PM
Edited Jun 24, 2013 at 4:12 PM
Piedone wrote:
I'm not sure how this should work but probably it should what you expect. However to override scripts from your theme you don't need to re-define it: just place a Script.js there too and it will be used instead the one in the module.
Yeah I tried with removing that and see if it did any difference, it didn't :-(


Also worth mentioning is that the theme in question derives from another theme, but the parent theme does not have that script file. Only the child theme and the module have the script, and it always takes it from the module, but I really need it to do it the other way around, so that when the parent theme is active, it will take the script from the module (since the script is abscent in the parent theme), and if the child theme is active then it should take the script from the child theme instead of the module.

Very frustrating :-(
Developer
Jun 24, 2013 at 4:27 PM
That's strange. Is the script under the very same path in the theme (i.e. Scripts/Script.js in module and theme too)? Would you mind trying with 1.x?
Jun 24, 2013 at 4:46 PM
Piedone wrote:
That's strange. Is the script under the very same path in the theme (i.e. Scripts/Script.js in module and theme too)? Would you mind trying with 1.x?
Yeah I tried with 1.x now but I'm getting the following error

Error 4 Assembly 'Orchard.Framework, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null' uses 'Autofac, Version=3.0.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da' which has a higher version than referenced assembly 'Autofac, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da' c:\Users\user\workspace\project\orchard\orchard\src\Orchard\bin\Release\Orchard.Framework.dll Project.CMS.Backend.Webshop

Do I need the WCF or Web Forms Integration one if I want to upgrade AutoFac?
Jun 25, 2013 at 12:49 PM
So far I have not been able to get this running, but if anyone else has any advice, I would greatly appreciate it, since this is blocking my work a bit at the moment.
My current solution is to rename all the scripts that exist in both the module and the theme, so that the theme will use unique names on all the scripts.

Not the most elegant solution I feel, but it will have to do for now.

I have currently tried with running the latest code on the 1.x branch, and I have also made sure that it uses Autofac 3.0.0, but the module I have written crashes because of that now, and I can't seem to get it to work, so I will have to drop it for a while and continue working.

A collegue of mine will help me later to get it running, but he's not around for a few weeks.

Anyway, is this a known bug?
Maybe someone can point me to a revision so that I can create a patch instead and patch the 1.6.1 that I'm running right now instead?
Developer
Jun 25, 2013 at 1:04 PM
Edited Jun 25, 2013 at 1:05 PM
Yeah I tried with 1.x now but I'm getting the following error

Error 4 Assembly 'Orchard.Framework, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null' uses 'Autofac, Version=3.0.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da' which has a higher version than referenced assembly 'Autofac, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da' c:\Users\user\workspace\project\orchard\orchard\src\Orchard\bin\Release\Orchard.Framework.dll Project.CMS.Backend.Webshop

Do I need the WCF or Web Forms Integration one if I want to upgrade AutoFac?
You need to set assembly binding redirect in web.config, that's all. Change:
      <dependentAssembly>
        <assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
        <bindingRedirect oldVersion="2.2.0.0-2.6.3.862" newVersion="2.6.3.862"/>
      </dependentAssembly>
to
      <dependentAssembly>
        <assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
        <bindingRedirect oldVersion="2.2.0.0-2.6.3.862" newVersion="3.0.0.0"/>
      </dependentAssembly>
Jun 25, 2013 at 2:24 PM
pszmyd wrote:
Yeah I tried with 1.x now but I'm getting the following error

Error 4 Assembly 'Orchard.Framework, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null' uses 'Autofac, Version=3.0.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da' which has a higher version than referenced assembly 'Autofac, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da' c:\Users\user\workspace\project\orchard\orchard\src\Orchard\bin\Release\Orchard.Framework.dll Project.CMS.Backend.Webshop

Do I need the WCF or Web Forms Integration one if I want to upgrade AutoFac?
You need to set assembly binding redirect in web.config, that's all. Change:
      <dependentAssembly>
        <assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
        <bindingRedirect oldVersion="2.2.0.0-2.6.3.862" newVersion="2.6.3.862"/>
      </dependentAssembly>
to
      <dependentAssembly>
        <assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
        <bindingRedirect oldVersion="2.2.0.0-2.6.3.862" newVersion="3.0.0.0"/>
      </dependentAssembly>
ah yeah, thanks, but still getting another exception related to my module.
Might be a common error so I might as well post it here then ^^
It should be noted that it works if I revert to Autofac 2.6 and Orchard 1.6.1 again.
I have never dealt with Autofac before so not sure how to fix this.
But like I said above, I have a collegue that will help me later, but that will take a while, so if anyone has any ideas, then I would greatly appreciate it :-)

An exception was thrown while invoking the constructor 'Void .ctor(Project.CMS.Modules.Webshop.Services.ISessionService, Orchard.Data.IRepository1[Project.CMS.Modules.Webshop.Records.CartItemRecord], Orchard.Data.IRepository1[Project.CMS.Modules.Webshop.Records.CartStatusRecord], Project.CMS.Backend.Webshop.ICategoryManager, Project.CMS.Backend.Webshop.IProductManager, Project.CMS.Backend.Webshop.IArticleManager, Project.CMS.Backend.Webshop.IPhotoManager, Project.CMS.Backend.Webshop.IThumbsManager, Project.WebApi.Client.EP.IOrdersClient)' on type 'CartManager'. ---> Value cannot be null.

at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Reflection\ConstructorParameterBinding.cs:line 137
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Reflection\ReflectionActivator.cs:line 122
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 79
at Autofac.Core.Resolving.InstanceLookup.<Execute>b__0() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 64
at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func1 creator) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Lifetime\LifetimeScope.cs:line 270
at Autofac.Core.Resolving.InstanceLookup.Execute() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 64
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\ResolveOperation.cs:line 123
at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 119
at Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass2.<CanSupplyValue>b__0() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Reflection\AutowiringParameter.cs:line 62
at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Reflection\ConstructorParameterBinding.cs:line 114
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Reflection\ReflectionActivator.cs:line 122
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 79
at Autofac.Core.Resolving.InstanceLookup.<Execute>b__0() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 64
at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func
1 creator) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Lifetime\LifetimeScope.cs:line 270
at Autofac.Core.Resolving.InstanceLookup.Execute() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 64
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\ResolveOperation.cs:line 123
at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 119
at Autofac.Features.Collections.CollectionRegistrationSource.<>c__DisplayClass4.<>c__DisplayClass6.<RegistrationsFor>b__1(IComponentRegistration cr) in c:\Projects\OSS\autofac\Core\Source\Autofac\Features\Collections\CollectionRegistrationSource.cs:line 75
at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext()
at System.Linq.Buffer
1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable
1 source)
at Autofac.Features.Collections.CollectionRegistrationSource.<>c__DisplayClass4.<RegistrationsFor>b__0(IComponentContext c, IEnumerable1 p) in c:\Projects\OSS\autofac\Core\Source\Autofac\Features\Collections\CollectionRegistrationSource.cs:line 75
at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Delegate\DelegateActivator.cs:line 68
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 79
at Autofac.Core.Resolving.InstanceLookup.Execute() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 62
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\ResolveOperation.cs:line 123
at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 119
at Autofac.Core.Registration.ExternalRegistrySource.<>c__DisplayClass8.<RegistrationsFor>b__3(IComponentContext c, IEnumerable
1 p) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Registration\ExternalRegistrySource.cs:line 80
at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Activators\Delegate\DelegateActivator.cs:line 68
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 79
at Autofac.Core.Resolving.InstanceLookup.Execute() in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\InstanceLookup.cs:line 62
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\ResolveOperation.cs:line 123
at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\ResolveOperation.cs:line 68
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Resolving\ResolveOperation.cs:line 85
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable
1 parameters) in c:\Projects\OSS\autofac\Core\Source\Autofac\Core\Lifetime\LifetimeScope.cs:line 232
at Autofac.Features.LazyDependencies.LazyRegistrationSource.<>c__DisplayClass51.<>c__DisplayClass7.<CreateLazyRegistration>b__4() in c:\Projects\OSS\autofac\Core\Source\Autofac\Features\LazyDependencies\LazyRegistrationSource.cs:line 85
at System.Lazy
1.CreateValue()
Developer
Jun 25, 2013 at 7:56 PM
Edited Jun 25, 2013 at 8:00 PM
You have a null reference exception being thrown inside your constructor.

Be sure to avoid putting any complex logic inside ctors (and if you do need - be extremely careful). Especially - never ever put anything that would result in resolving other objects from the container. Otherwise you're gonna see NREs (or SOEs) because when the ctor is called, the object hierarchy is not yet fully constructed...

The rule of thumb should be to perform variable assignments within ctor only.