diff --git a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs index 5200dced90..9cd54fe7b8 100644 --- a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs +++ b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs @@ -16,9 +16,9 @@ namespace Umbraco.Core.Composing.LightInject /// /// Initializes a new instance of the with a LightInject container. /// - protected LightInjectContainer(ServiceContainer container) + public LightInjectContainer(ServiceContainer container) { - Container = container; + Container = ConfigureContainer(container); } /// @@ -33,7 +33,12 @@ namespace Umbraco.Core.Composing.LightInject protected static ServiceContainer CreateServiceContainer() { var container = new ServiceContainer(new ContainerOptions { EnablePropertyInjection = false }); + ConfigureContainer(container); + return container; + } + private static ServiceContainer ConfigureContainer(ServiceContainer container) + { // note: the block below is disabled, as it is too LightInject-specific // // supports annotated constructor injections diff --git a/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs b/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs index 8f842e14fe..4a73795f68 100644 --- a/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs +++ b/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs @@ -9,6 +9,8 @@ namespace Umbraco.Core.Composing /// public static class RegisterFactory { + //TODO This needs to die + // cannot use typeof().AssemblyQualifiedName on the web container - we don't reference it // a normal Umbraco site should run on the web container, but an app may run on the core one private const string CoreLightInjectContainerTypeName = "Umbraco.Core.Composing.LightInject.LightInjectContainer,Umbraco.Core"; diff --git a/src/Umbraco.Tests.Integration/CrossWireContainer.cs b/src/Umbraco.Tests.Integration/CrossWireContainer.cs new file mode 100644 index 0000000000..1bf5d4fb1c --- /dev/null +++ b/src/Umbraco.Tests.Integration/CrossWireContainer.cs @@ -0,0 +1,83 @@ +using LightInject; +using LightInject.Microsoft.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using NUnit.Framework; +using System; +using System.IO; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Composing; +using Umbraco.Core.Composing.LightInject; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; + +namespace Umbraco.Tests.Integration +{ + [TestFixture] + public class CrossWireContainer + { + [Test] + public void CrossWire() + { + // MSDI + var services = new ServiceCollection(); + services.AddSingleton(); + var msdiServiceProvider = services.BuildServiceProvider(); + + // LightInject + var liContainer = new ServiceContainer(ContainerOptions.Default.WithMicrosoftSettings()); + var liServiceProvider = liContainer.CreateServiceProvider(services); + + // Umbraco + var umbracoContainer = new LightInjectContainer(liContainer); + + // Dependencies needed for creating composition/register essentials + var tempPath = Path.Combine(Path.GetTempPath(), "umbraco-temp-" + Guid.NewGuid()); + if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath); + var globalSettings = Mock.Of(); + var typeFinder = Mock.Of(); + var ioHelper = Mock.Of(); + var runtimeCache = NoAppCache.Instance; + var logger = Mock.Of(); + var typeLoader = new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(tempPath), logger, false); + var runtimeState = Mock.Of(); + var configs = new Configs(x => null); + var appCaches = new AppCaches(runtimeCache, NoAppCache.Instance, new IsolatedCaches(type => new ObjectCacheAppCache(typeFinder))); + var profiler = new VoidProfiler(); + var mainDom = Mock.Of(); + var umbracoDatabaseFactory = Mock.Of(); + var umbracoVersion = new UmbracoVersion(); + var dbProviderFactoryCreator = Mock.Of(); + + // Register in the container + var composition = new Composition(umbracoContainer, typeLoader, logger, runtimeState, configs, ioHelper, appCaches); + composition.RegisterEssentials(logger, profiler, logger, mainDom, appCaches, umbracoDatabaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, dbProviderFactoryCreator); + + // Resolve + + // From MSDI + var foo1 = msdiServiceProvider.GetService(); + var foo2 = liServiceProvider.GetService(); + var foo3 = umbracoContainer.GetInstance(); + + Assert.IsNotNull(foo1); + Assert.IsNotNull(foo2); + Assert.IsNotNull(foo3); + + // These are not the same because cross wiring means copying the container, not falling back to a container + Assert.AreNotSame(foo1, foo2); + // These are the same because the umbraco container wraps the light inject container + Assert.AreSame(foo2, foo3); + } + + private class Foo + { + public Foo() + { + } + } + } +} diff --git a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj new file mode 100644 index 0000000000..5d8ae11ea2 --- /dev/null +++ b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -0,0 +1,26 @@ + + + + Exe + netcoreapp3.1 + false + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + diff --git a/src/umbraco.sln b/src/umbraco.sln index f98f7e034e..9f24434789 100644 --- a/src/umbraco.sln +++ b/src/umbraco.sln @@ -117,9 +117,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Examine.Lucene", "U EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.BackOffice", "Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj", "{9B95EEF7-63FE-4432-8C63-166BE9C1A929}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Web.UI.NetCore", "Umbraco.Web.UI.NetCore\Umbraco.Web.UI.NetCore.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.UI.NetCore", "Umbraco.Web.UI.NetCore\Umbraco.Web.UI.NetCore.csproj", "{DCDFE97C-5630-4F6F-855D-8AEEB96556A5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Web.Website", "Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Website", "Umbraco.Web.Website\Umbraco.Web.Website.csproj", "{5A246D54-3109-4D2B-BE7D-FC0787D126AE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.Integration", "Umbraco.Tests.Integration\Umbraco.Tests.Integration.csproj", "{D6319409-777A-4BD0-93ED-B2DFD805B32C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -189,6 +191,10 @@ Global {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Debug|Any CPU.Build.0 = Debug|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Release|Any CPU.ActiveCfg = Release|Any CPU {5A246D54-3109-4D2B-BE7D-FC0787D126AE}.Release|Any CPU.Build.0 = Release|Any CPU + {D6319409-777A-4BD0-93ED-B2DFD805B32C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6319409-777A-4BD0-93ED-B2DFD805B32C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6319409-777A-4BD0-93ED-B2DFD805B32C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6319409-777A-4BD0-93ED-B2DFD805B32C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -202,6 +208,7 @@ Global {3A33ADC9-C6C0-4DB1-A613-A9AF0210DF3D} = {B5BD12C1-A454-435E-8A46-FF4A364C0382} {C7311C00-2184-409B-B506-52A5FAEA8736} = {FD962632-184C-4005-A5F3-E705D92FC645} {FB5676ED-7A69-492C-B802-E7B24144C0FC} = {B5BD12C1-A454-435E-8A46-FF4A364C0382} + {D6319409-777A-4BD0-93ED-B2DFD805B32C} = {B5BD12C1-A454-435E-8A46-FF4A364C0382} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7A0F2E34-D2AF-4DAB-86A0-7D7764B3D0EC}