diff --git a/src/Orchard.Tests/Environment/OrchardStarterTests.cs b/src/Orchard.Tests/Environment/OrchardStarterTests.cs index b24eebe67..7d22ca68c 100644 --- a/src/Orchard.Tests/Environment/OrchardStarterTests.cs +++ b/src/Orchard.Tests/Environment/OrchardStarterTests.cs @@ -1,4 +1,6 @@ -using System.Web.Mvc; +using System.Collections.Generic; +using System.Linq; +using System.Web.Mvc; using Autofac; using NUnit.Framework; using Orchard.Environment; @@ -11,5 +13,34 @@ namespace Orchard.Tests.Environment { var host = OrchardStarter.CreateHost(b => b.RegisterInstance(new ControllerBuilder())); Assert.That(host, Is.TypeOf()); } + + [Test] + public void ContainerResolvesServicesInSameOrderTheyAreRegistered() { + var container = OrchardStarter.CreateHostContainer(builder => { + builder.RegisterType().As(); + builder.RegisterType().As(); + }); + var services = container.Resolve>(); + Assert.That(services.Count(), Is.EqualTo(2)); + Assert.That(services.First(), Is.TypeOf()); + Assert.That(services.Last(), Is.TypeOf()); + } + + [Test] + public void MostRecentlyRegisteredServiceReturnsFromSingularResolve() { + var container = OrchardStarter.CreateHostContainer(builder => { + builder.RegisterType().As(); + builder.RegisterType().As(); + }); + var service = container.Resolve(); + Assert.That(service, Is.Not.Null); + Assert.That(service, Is.TypeOf()); + } + + public interface IServiceA {} + + public class Component1 : IServiceA {} + + public class Component2 : IServiceA {} } -} +} \ No newline at end of file diff --git a/src/Orchard/Environment/CollectionOrderModule.cs b/src/Orchard/Environment/CollectionOrderModule.cs new file mode 100644 index 000000000..bf48644df --- /dev/null +++ b/src/Orchard/Environment/CollectionOrderModule.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections; +using Autofac.Core; + +namespace Orchard.Environment { + internal class CollectionOrderModule : IModule { + public void Configure(IComponentRegistry componentRegistry) { + componentRegistry.Registered += (sender, registered) => { + // only bother watching enumerable resolves + var limitType = registered.ComponentRegistration.Activator.LimitType; + if (typeof(IEnumerable).IsAssignableFrom(limitType)) { + registered.ComponentRegistration.Activated += (sender2, activated) => { + // Autofac's IEnumerable feature returns an Array + if (activated.Instance is Array) { + // Orchard needs FIFO, not FILO, component order + Array.Reverse((Array)activated.Instance); + } + }; + } + }; + } + } +} diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 5f4b1e1c9..41fd63bda 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -31,6 +31,7 @@ namespace Orchard.Environment { public static class OrchardStarter { public static IContainer CreateHostContainer(Action registrations) { var builder = new ContainerBuilder(); + builder.RegisterModule(new CollectionOrderModule()); builder.RegisterModule(new LoggingModule()); builder.RegisterModule(new EventsModule()); builder.RegisterModule(new CacheModule()); diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 0f92e087e..314b697ca 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -174,6 +174,7 @@ +