Martin Brenn avatar Martin Brenn committed b910a7c

ActivationBlock support now other scopes

Comments (0)

Files changed (4)

src/LocalizationBS.Designer.cs

 //------------------------------------------------------------------------------
 // <auto-generated>
 //     Dieser Code wurde von einem Tool generiert.
-//     Laufzeitversion:4.0.30319.239
+//     Laufzeitversion:4.0.30319.269
 //
 //     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
 //     der Code erneut generiert wird.
         }
         
         /// <summary>
+        ///   Sucht eine lokalisierte Zeichenfolge, die Kein ActivationBlock gefunden, dessen Kriterien passen: Aktivierungsbedingungen: {0} ähnelt.
+        /// </summary>
+        internal static string NoScopeFoundForListOfEnablers {
+            get {
+                return ResourceManager.GetString("NoScopeFoundForListOfEnablers", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Sucht eine lokalisierte Zeichenfolge, die Das Assembly &apos;{0}&apos; wurde nicht gefunden. ähnelt.
         /// </summary>
         internal static string PluginLoader_AssemblyNotFound {

src/LocalizationBS.resx

   <data name="Mapper_WrongTypeForDatabaseKeyAttribute" xml:space="preserve">
     <value>Die Eigenschaft mit dem Attribut 'DatabaseKeyAttribute' muss vom Typ System.Int32 oder System.Int64 sein. </value>
   </data>
+  <data name="NoScopeFoundForListOfEnablers" xml:space="preserve">
+    <value>Kein ActivationBlock gefunden, dessen Kriterien passen: Aktivierungsbedingungen: {0}</value>
+  </data>
   <data name="PluginLoader_AssemblyNotFound" xml:space="preserve">
     <value>Das Assembly '{0}' wurde nicht gefunden.</value>
   </data>

src/ObjectActivation/ActivationBlock.cs

         /// <summary>
         /// Gets an inner block that may already contain the required object.
         /// </summary>
-        internal ActivationBlock InnerBlock
+        internal ActivationBlock OuterBlock
         {
             get { return this.outerBlock; }
         }
                 "ActivationBlock: {0}",
                 this.Name);
         }
+
+        /// <summary>
+        /// Finds the activation block, matching to the given function
+        /// </summary>
+        /// <param name="where">Condition of the function</param>
+        /// <returns>Found Activationblock</returns>
+        public ActivationBlock FindActivationBlockInChain(Func<ActivationBlock, bool> where)
+        {
+            var currentActivationBlock = this;
+
+            while (currentActivationBlock != null)
+            {
+                if (where(currentActivationBlock))
+                {
+                    return currentActivationBlock;
+                }
+
+                // Try to add to the next outer scope
+                currentActivationBlock = currentActivationBlock.OuterBlock;
+            }
+
+            return null;
+
+        }
     }
 }

src/ObjectActivation/BindingHelperExtension.cs

 using BurnSystems.ObjectActivation.Enabler;
 using System.Linq.Expressions;
 using System.Collections.Generic;
+using System.Text;
 
 namespace BurnSystems.ObjectActivation
 {
         /// <returns>The binding helper</returns>
         public static BindingHelper AsScoped(this BindingHelper helper)
         {
+            return AsScopedIn(helper, x => true);
+        }
+
+        /// <summary>
+        /// Marks the current binding as scoped, which means that 
+        /// the same instance shall be returned, when it has been created 
+        /// within the same scope. 
+        /// Scopes are defined by Activation Block.
+        /// When the object is used within activation block, 
+        /// the instance will be created during each resolution request.
+        /// </summary>
+        /// <param name="helper">Binding helper to be used</param>
+        /// <param name="where">Condition, whose scope shall be used for automatic disposing</param>
+        /// <returns>The binding helper</returns>
+        public static BindingHelper AsScopedIn(this BindingHelper helper, Func<ActivationBlock, bool> where)
+        {
             // As Scoped is not allowed in ActivationContainer
             // Only within activation blocks, the disposal has to be organized. 
             var oldContainerFactory = helper.ActivationInfo.FactoryActivationBlock;
             helper.ActivationInfo.FactoryActivationBlock =
                 (x, y) =>
                 {
+                    var relevantActivationBlock = x.FindActivationBlockInChain(where);
+                    if (relevantActivationBlock == null)
+                    {
+                        // No activation block matches
+                        var enablerText = new StringBuilder();
+                        foreach (var enabler in y)
+                        {
+                            enablerText.AppendLine(enablerText.ToString());
+                        }
+
+                        throw new InvalidOperationException(LocalizationBS.NoScopeFoundForListOfEnablers + enablerText.ToString());
+                    }
+
                     var found =
-                        x.ActiveInstances.Find(helper.ActivationInfo);
+                        relevantActivationBlock.ActiveInstances.Find(helper.ActivationInfo);
 
                     if (found == null)
                     {
                         found = oldContainerFactory(x, y);
 
-                        x.Add(
-                            new ActiveInstance()
-                            {
-                                Criterias = helper.ActivationInfo.CriteriaCatalogue,
-                                Value = found
-                            });
+                        // Ok, Add to first match
+
+                        if (relevantActivationBlock != null)
+                        {
+                            relevantActivationBlock.Add(
+                                new ActiveInstance()
+                                {
+                                    Criterias = helper.ActivationInfo.CriteriaCatalogue,
+                                    Value = found
+                                });
+                        }
                     }
 
                     return found;
 
             return helper;
         }
+
+        /// <summary>
+        /// Marks the current binding as scoped, which means that 
+        /// the same instance shall be returned, when it has been created 
+        /// within the same scope. 
+        /// Scopes are defined by Activation Blocks.
+        /// The name of the activation block defines, whose scope will be used for automatic disposing
+        /// </summary>
+        /// <param name="helper">Binding helper to be used</param>
+        /// <param name="nameOfActivationBlock">Name of block, whose scope shall be used for automatic disposing</param>
+        /// <returns>The binding helper</returns>
+        public static BindingHelper AsScopedIn(this BindingHelper helper, string nameOfActivationBlock)
+        {
+            return AsScopedIn(helper, x => x.Name == nameOfActivationBlock);
+        }
     }
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.