DotvvmChildEventCallback

Add/wire-up Castle.Windsor IOC container Add custom WindsorVIewModelLoader

7/5/2023 1:19:11 PM

Details

diff --git a/src/Web/Controls/ConfirmationModal/ConfirmationModalConfigurationExtensions.cs b/src/Web/Controls/ConfirmationModal/ConfirmationModalConfigurationExtensions.cs
index 270216a..c71a00f 100644
--- a/src/Web/Controls/ConfirmationModal/ConfirmationModalConfigurationExtensions.cs
+++ b/src/Web/Controls/ConfirmationModal/ConfirmationModalConfigurationExtensions.cs
@@ -2,7 +2,7 @@ namespace Web.Controls.ConfirmationModal
 {
     using DotVVM.Framework.Configuration;
     using DotVVM.Framework.ResourceManagement;
-    using Helper;
+    using Helpers;
 
     public static class ConfirmationModalConfigurationExtensions
     {
diff --git a/src/Web/Controls/WizardNavigation/WizardNavigationConfigurationExtensions.cs b/src/Web/Controls/WizardNavigation/WizardNavigationConfigurationExtensions.cs
index be65d26..7f60d15 100644
--- a/src/Web/Controls/WizardNavigation/WizardNavigationConfigurationExtensions.cs
+++ b/src/Web/Controls/WizardNavigation/WizardNavigationConfigurationExtensions.cs
@@ -1,7 +1,7 @@
 namespace Web.Controls.WizardNavigation
 {
     using DotVVM.Framework.Configuration;
-    using Helper;
+    using Helpers;
 
     public static class WizardNavigationConfigurationExtensions
     {
diff --git a/src/Web/DotvvmStartup.cs b/src/Web/DotvvmStartup.cs
index 49063b3..5f3e520 100644
--- a/src/Web/DotvvmStartup.cs
+++ b/src/Web/DotvvmStartup.cs
@@ -5,7 +5,7 @@ namespace Web
     using DotVVM.Framework.Configuration;
     using DotVVM.Framework.Controls.Bootstrap4;
     using DotVVM.Framework.ResourceManagement;
-    using Helper;
+    using Helpers;
     using Microsoft.Extensions.DependencyInjection;
 
     public class DotVvmStartup : IDotvvmStartup, IDotvvmServiceConfigurator
@@ -28,7 +28,8 @@ namespace Web
 
         public void ConfigureServices(IDotvvmServiceCollection options)
         {
-            options.AddDefaultTempStorages(Constants.DefaultTemporaryStoragePath);
+            options.ConfigureCastleWindsor();
+            options.ConfigureDefaultTemporaryStorage();
             //options.AddHotReload();
         }
 
diff --git a/src/Web/Helpers/DotVvmServiceCollectionExtensions.cs b/src/Web/Helpers/DotVvmServiceCollectionExtensions.cs
new file mode 100644
index 0000000..6f0d4f7
--- /dev/null
+++ b/src/Web/Helpers/DotVvmServiceCollectionExtensions.cs
@@ -0,0 +1,46 @@
+namespace Web.Helpers
+{
+    using Castle.MicroKernel.Registration;
+    using Castle.Windsor;
+    using DotVVM.Framework.ViewModel.Serialization;
+    using Microsoft.Extensions.DependencyInjection;
+    using System.IO;
+    using System.Web.Hosting;
+    using Infrastructure;
+
+    public static class DotVvmServiceCollectionExtensions
+    {
+        private static WindsorContainer _windsorContainer;
+
+        // https://www.dotvvm.com/docs/2.0/pages/advanced-ioc-di-container-owin
+        public static IDotvvmServiceCollection ConfigureCastleWindsor(this IDotvvmServiceCollection svc)
+        {
+            _windsorContainer = new WindsorContainer();
+
+            // ReSharper disable once PossibleNullReferenceException
+            _windsorContainer.Register(Classes.FromThisAssembly()
+                .InNamespace(Constants.ViewModelsNamespace)
+                .LifestyleTransient()
+                .WithServiceDefaultInterfaces());
+            _windsorContainer.Kernel.Resolver.AddSubResolver(new ServiceCollectionResolver(svc.Services));
+
+            svc.Services.AddSingleton<IViewModelLoader>(_ => new WindsorViewModelLoader(_windsorContainer));
+            svc.RegisterDependencies();
+            return svc;
+        }
+
+        public static IDotvvmServiceCollection ConfigureDefaultTemporaryStorage(this IDotvvmServiceCollection svc)
+        {
+            var path = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, Constants.DefaultTemporaryStoragePath);
+            svc.AddDefaultTempStorages(path);
+            return svc;
+        }
+
+        #region Private Methods
+        private static IDotvvmServiceCollection RegisterDependencies(this IDotvvmServiceCollection svc)
+        {
+            return svc;
+        }
+        #endregion
+    }
+}
diff --git a/src/Web/Infrastructure/ServiceCollectionResolver.cs b/src/Web/Infrastructure/ServiceCollectionResolver.cs
new file mode 100644
index 0000000..8e5c5d0
--- /dev/null
+++ b/src/Web/Infrastructure/ServiceCollectionResolver.cs
@@ -0,0 +1,34 @@
+namespace Web.Infrastructure
+{
+    using Castle.Core;
+    using Castle.MicroKernel.Context;
+    using Castle.MicroKernel;
+    using Microsoft.Extensions.DependencyInjection;
+    using System.Diagnostics;
+    using System.Linq;
+
+    [DebuggerStepThrough]
+    public class ServiceCollectionResolver : ISubDependencyResolver
+    {
+        public IServiceCollection Container { get; }
+
+        [DebuggerStepThrough]
+        public ServiceCollectionResolver(IServiceCollection container)
+        {
+            Container = container;
+        }
+
+        [DebuggerStepThrough]
+        public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
+        {
+            return Container.Any(x => x.ServiceType == dependency.TargetType);
+        }
+
+        [DebuggerStepThrough]
+        public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
+        {
+            var provider = Container.BuildServiceProvider();
+            return provider.GetService(dependency.TargetType);
+        }
+    }
+}
diff --git a/src/Web/Infrastructure/WindsorViewModelLoader.cs b/src/Web/Infrastructure/WindsorViewModelLoader.cs
new file mode 100644
index 0000000..067ffed
--- /dev/null
+++ b/src/Web/Infrastructure/WindsorViewModelLoader.cs
@@ -0,0 +1,28 @@
+namespace Web.Infrastructure
+{
+    using Castle.Windsor;
+    using DotVVM.Framework.Hosting;
+    using DotVVM.Framework.ViewModel.Serialization;
+    using System;
+
+    public class WindsorViewModelLoader : DefaultViewModelLoader
+    {
+        private readonly WindsorContainer _container;
+
+        public WindsorViewModelLoader(WindsorContainer container)
+        {
+            _container = container;
+        }
+
+        protected override object CreateViewModelInstance(Type viewModelType, IDotvvmRequestContext context)
+        {
+            return _container.Resolve(viewModelType);
+        }
+
+        public override void DisposeViewModel(object instance)
+        {
+            _container.Release(instance);
+            base.DisposeViewModel(instance);
+        }
+    }
+}
diff --git a/src/Web/packages.config b/src/Web/packages.config
index 44b9546..4e71d7b 100644
--- a/src/Web/packages.config
+++ b/src/Web/packages.config
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Ben.Demystifier" version="0.4.1" targetFramework="net48" />
+  <package id="Castle.Core" version="4.4.1" targetFramework="net48" />
+  <package id="Castle.Windsor" version="5.1.2" targetFramework="net48" />
   <package id="DotVVM" version="4.1.7" targetFramework="net48" />
   <package id="DotVVM.Controls.Bootstrap4" version="4.1.3" targetFramework="net48" />
   <package id="DotVVM.Core" version="4.1.7" targetFramework="net48" />

src/Web/Web.csproj 12(+11 -1)

diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj
index 8deca42..31601a0 100644
--- a/src/Web/Web.csproj
+++ b/src/Web/Web.csproj
@@ -42,6 +42,12 @@
     <Reference Include="Ben.Demystifier, Version=0.4.0.0, Culture=neutral, PublicKeyToken=a6d206e05440431a, processorArchitecture=MSIL">
       <HintPath>..\packages\Ben.Demystifier.0.4.1\lib\net45\Ben.Demystifier.dll</HintPath>
     </Reference>
+    <Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+      <HintPath>..\packages\Castle.Core.4.4.1\lib\net45\Castle.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Castle.Windsor, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+      <HintPath>..\packages\Castle.Windsor.5.1.2\lib\net45\Castle.Windsor.dll</HintPath>
+    </Reference>
     <Reference Include="DotVVM.Core, Version=4.1.7.0, Culture=neutral, PublicKeyToken=23f3607db32275da, processorArchitecture=MSIL">
       <HintPath>..\packages\DotVVM.Core.4.1.7\lib\net472\DotVVM.Core.dll</HintPath>
     </Reference>
@@ -162,6 +168,7 @@
       <Private>True</Private>
       <Private>True</Private>
     </Reference>
+    <Reference Include="System.Runtime.Remoting" />
     <Reference Include="System.Security" />
     <Reference Include="System.Security.Claims, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Security.Claims.4.3.0\lib\net46\System.Security.Claims.dll</HintPath>
@@ -196,7 +203,10 @@
     <Compile Include="Controls\WizardNavigation\WizardNavigation.cs" />
     <Compile Include="Controls\WizardNavigation\WizardNavigationConfigurationExtensions.cs" />
     <Compile Include="Controls\WizardNavigation\WizardNavigationViewModel.cs" />
-    <Compile Include="Helper\Constants.cs" />
+    <Compile Include="Helpers\Constants.cs" />
+    <Compile Include="Helpers\DotVvmServiceCollectionExtensions.cs" />
+    <Compile Include="Infrastructure\ServiceCollectionResolver.cs" />
+    <Compile Include="Infrastructure\WindsorViewModelLoader.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Startup.cs" />
     <Compile Include="DotVvmStartup.cs" />