lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nightowl...@apache.org
Subject [2/4] lucenenet git commit: BUG: Lazy-initialize the default codec and delay any Reflection code until the first access to DefaultCodecFactory, DefaultDocValuesFactory, and DefaultPostingsFormatFactory. Also don't use Activator.CreateInstance(Type, bool)
Date Thu, 18 May 2017 11:58:26 GMT
BUG: Lazy-initialize the default codec and delay any Reflection code until the first access
to DefaultCodecFactory, DefaultDocValuesFactory, and DefaultPostingsFormatFactory. Also don't
use Activator.CreateInstance(Type, bool) with nonPublic unless the current AppDomain is running
in full trust.


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/8a58d858
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/8a58d858
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/8a58d858

Branch: refs/heads/master
Commit: 8a58d858b99ec7bae2430e9cb0c24938c80f1bf6
Parents: 675fc16
Author: Shad Storhaug <shad@shadstorhaug.com>
Authored: Thu May 18 18:50:22 2017 +0700
Committer: Shad Storhaug <shad@shadstorhaug.com>
Committed: Thu May 18 18:53:26 2017 +0700

----------------------------------------------------------------------
 .../Codecs/TestCodecFactory.cs                  |  3 +-
 .../Codecs/TestDocValuesFormatFactory.cs        |  3 +-
 .../Codecs/TestPostingsFormatFactory.cs         |  3 +-
 .../Util/LuceneTestCase.cs                      |  2 -
 src/Lucene.Net/Codecs/Codec.cs                  | 19 ++++---
 .../Support/Codecs/DefaultCodecFactory.cs       | 43 +++++++++++-----
 .../Codecs/DefaultDocValuesFormatFactory.cs     | 43 +++++++++++-----
 .../Codecs/DefaultPostingsFormatFactory.cs      | 45 +++++++++++------
 .../Support/Util/NamedServiceFactory.cs         | 52 +++++++++++++++++---
 9 files changed, 151 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net.TestFramework/Codecs/TestCodecFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Codecs/TestCodecFactory.cs b/src/Lucene.Net.TestFramework/Codecs/TestCodecFactory.cs
index e19037e..874bac2 100644
--- a/src/Lucene.Net.TestFramework/Codecs/TestCodecFactory.cs
+++ b/src/Lucene.Net.TestFramework/Codecs/TestCodecFactory.cs
@@ -29,8 +29,9 @@ namespace Lucene.Net.Codecs
     /// </summary>
     public class TestCodecFactory : DefaultCodecFactory
     {
-        public TestCodecFactory()
+        protected override void Initialize()
         {
+            base.Initialize();
             base.ScanForCodecs(this.GetType().GetTypeInfo().Assembly);
         }
 

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net.TestFramework/Codecs/TestDocValuesFormatFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Codecs/TestDocValuesFormatFactory.cs b/src/Lucene.Net.TestFramework/Codecs/TestDocValuesFormatFactory.cs
index 813d5c5..2c83ca7 100644
--- a/src/Lucene.Net.TestFramework/Codecs/TestDocValuesFormatFactory.cs
+++ b/src/Lucene.Net.TestFramework/Codecs/TestDocValuesFormatFactory.cs
@@ -28,8 +28,9 @@ namespace Lucene.Net.Codecs
     /// </summary>
     public class TestDocValuesFormatFactory : DefaultDocValuesFormatFactory
     {
-        public TestDocValuesFormatFactory()
+        protected override void Initialize()
         {
+            base.Initialize();
             base.ScanForDocValuesFormats(this.GetType().GetTypeInfo().Assembly);
         }
     }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net.TestFramework/Codecs/TestPostingsFormatFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Codecs/TestPostingsFormatFactory.cs b/src/Lucene.Net.TestFramework/Codecs/TestPostingsFormatFactory.cs
index 64a7188..a0bec24 100644
--- a/src/Lucene.Net.TestFramework/Codecs/TestPostingsFormatFactory.cs
+++ b/src/Lucene.Net.TestFramework/Codecs/TestPostingsFormatFactory.cs
@@ -28,8 +28,9 @@ namespace Lucene.Net.Codecs
     /// </summary>
     public class TestPostingsFormatFactory : DefaultPostingsFormatFactory
     {
-        public TestPostingsFormatFactory()
+        protected override void Initialize()
         {
+            base.Initialize();
             base.ScanForPostingsFormats(this.GetType().GetTypeInfo().Assembly);
         }
     }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
index 2796502..8f3eaf3 100644
--- a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs
@@ -639,8 +639,6 @@ namespace Lucene.Net.Util
             DocValuesFormat.SetDocValuesFormatFactory(TEST_DOCVALUES_FORMAT_FACTORY);
             PostingsFormat.SetPostingsFormatFactory(TEST_POSTINGS_FORMAT_FACTORY);
 
-            // IMPORTANT: Call this line after calling Codec.SetCodecFactory() because both
-            // of them change Codec.Default
             ClassEnvRule.Before(this);
         }
 

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net/Codecs/Codec.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Codecs/Codec.cs b/src/Lucene.Net/Codecs/Codec.cs
index 34c083e..816547c 100644
--- a/src/Lucene.Net/Codecs/Codec.cs
+++ b/src/Lucene.Net/Codecs/Codec.cs
@@ -60,15 +60,9 @@ namespace Lucene.Net.Codecs
     // the Java-centric NamedSPILoader
     public abstract class Codec //: NamedSPILoader.INamedSPI
     {
-        private static ICodecFactory codecFactory;
+        private static ICodecFactory codecFactory = new DefaultCodecFactory();
         private readonly string name;
 
-        static Codec()
-        {
-            codecFactory = new DefaultCodecFactory();
-            defaultCodec = Codec.ForName("Lucene46");
-        }
-
         /// <summary>
         /// Sets the <see cref="ICodecFactory"/> instance used to instantiate
         /// <see cref="Codec"/> subclasses.
@@ -80,7 +74,6 @@ namespace Lucene.Net.Codecs
             if (codecFactory == null)
                 throw new ArgumentNullException("codecFactory");
             Codec.codecFactory = codecFactory;
-            defaultCodec = Codec.ForName("Lucene46");
         }
 
         /// <summary>
@@ -95,13 +88,13 @@ namespace Lucene.Net.Codecs
         /// <summary>
         /// Creates a new codec.
         /// <para/>
-        /// The provided name will be written into the index segment: in order for
+        /// The <see cref="Codec.Name"/> will be written into the index segment: in
order for
         /// the segment to be read this class should be registered by subclassing <see
cref="DefaultCodecFactory"/> and
         /// calling <see cref="DefaultCodecFactory.ScanForCodecs(System.Reflection.Assembly)"/>
in the class constructor. 
         /// The new <see cref="ICodecFactory"/> can be registered by calling <see
cref="SetCodecFactory"/> at application startup.</summary>
         protected Codec()
         {
-            this.name = NamedServiceFactory<Codec>.GetServiceName(this.GetType());
+            name = NamedServiceFactory<Codec>.GetServiceName(this.GetType());
         }
 
         /// <summary>
@@ -181,6 +174,12 @@ namespace Lucene.Net.Codecs
         {
             get
             {
+                // Lazy load the default codec if not already supplied
+                if (defaultCodec == null)
+                {
+                    defaultCodec = Codec.ForName("Lucene46");
+                }
+
                 return defaultCodec;
             }
             set

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs b/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
index 1499596..18084c9 100644
--- a/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
+++ b/src/Lucene.Net/Support/Codecs/DefaultCodecFactory.cs
@@ -36,11 +36,11 @@ namespace Lucene.Net.Codecs
     ///     <item>subclass <see cref="DefaultCodecFactory"/> and override
     ///         <see cref="DefaultCodecFactory.GetCodecType(string)"/> so a type new
type can be
     ///         supplied that is not in the <see cref="DefaultCodecFactory.codecNameToTypeMap"/>.</item>
+    ///     <item>subclass <see cref="DefaultCodecFactory"/> to add new or override
the default <see cref="Codec"/> 
+    ///         types by overriding <see cref="Initialize()"/> and calling <see
cref="PutPostingsFormatType(Type)"/>.</item>
     ///     <item>subclass <see cref="DefaultCodecFactory"/> to scan additional
assemblies for <see cref="Codec"/>
-    ///         subclasses in the constructor by calling <see cref="ScanForCodecs(Assembly)"/>.

+    ///         subclasses in by overriding <see cref="Initialize()"/> and calling
<see cref="ScanForPostingsFormats(Assembly)"/>. 
     ///         For performance reasons, the default behavior only loads Lucene.Net codecs.</item>
-    ///     <item>subclass <see cref="DefaultCodecFactory"/> to add override
the default <see cref="Codec"/> 
-    ///         types by calling <see cref="PutCodecType(Type)"/>.</item>
     /// </list>
     /// <para/>
     /// To set the <see cref="ICodecFactory"/>, call <see cref="Codec.SetCodecFactory(ICodecFactory)"/>.
@@ -51,8 +51,18 @@ namespace Lucene.Net.Codecs
         // variable in the Codec class.
         private readonly IDictionary<string, Type> codecNameToTypeMap = new Dictionary<string,
Type>();
         private readonly IDictionary<Type, Codec> codecInstanceCache = new Dictionary<Type,
Codec>();
+        private object syncLock = new object();
 
-        public DefaultCodecFactory()
+        /// <summary>
+        /// Initializes the codec type cache with the known <see cref="Codec"/> types.
+        /// Override this method (and optionally call <c>base.Initialize()</c>)
to add your
+        /// own <see cref="Codec"/> types by calling <see cref="PutCodecType(Type)"/>

+        /// or <see cref="ScanForCodecs(Assembly)"/>.
+        /// <para/>
+        /// If two types have the same name by using the <see cref="CodecNameAttribute"/>,
the
+        /// last one registered wins.
+        /// </summary>
+        protected override void Initialize()
         {
             ScanForCodecs(new Assembly[] {
                 typeof(Codec).GetTypeInfo().Assembly,
@@ -111,7 +121,7 @@ namespace Lucene.Net.Codecs
             }
             if (!typeof(Codec).GetTypeInfo().IsAssignableFrom(codec))
             {
-                throw new ArgumentException("System.Type passed dose not subclass Codec.");
+                throw new ArgumentException("The supplied codec does not subclass Codec.");
             }
 
             PutCodecTypeImpl(codec);
@@ -130,8 +140,8 @@ namespace Lucene.Net.Codecs
         /// <returns>The <see cref="Codec"/> instance.</returns>
         public virtual Codec GetCodec(string name)
         {
+            EnsureInitialized(); // Safety in case a subclass doesn't call it
             Type codecType = GetCodecType(name);
-
             return GetCodec(codecType);
         }
 
@@ -145,8 +155,14 @@ namespace Lucene.Net.Codecs
             Codec instance;
             if (!codecInstanceCache.TryGetValue(type, out instance))
             {
-                instance = (Codec)Activator.CreateInstance(type, true);
-                codecInstanceCache[type] = instance;
+                lock (syncLock)
+                {
+                    if (!codecInstanceCache.TryGetValue(type, out instance))
+                    {
+                        instance = (Codec)Activator.CreateInstance(type, IsFullyTrusted);
+                        codecInstanceCache[type] = instance;
+                    }
+                }
             }
 
             return instance;
@@ -159,13 +175,13 @@ namespace Lucene.Net.Codecs
         /// <returns>The <see cref="Codec"/> <see cref="Type"/>.</returns>
         protected virtual Type GetCodecType(string name)
         {
+            EnsureInitialized();
             Type codecType;
-            codecNameToTypeMap.TryGetValue(name, out codecType);
-            if (codecType == null)
+            if (!codecNameToTypeMap.TryGetValue(name, out codecType) && codecType
== null)
             {
                 throw new ArgumentException(string.Format("Codec '{0}' cannot be loaded.
If the codec is not " +
-                    "in a Lucene.Net assembly, you must subclass DefaultCodecFactory and
call ScanForCodecs() with the " + 
-                    "target assembly from the subclass constructor.", name));
+                    "in a Lucene.Net assembly, you must subclass DefaultCodecFactory and
call PutCodecType() or " + 
+                    "ScanForCodecs() from the Initialize() method.", name));
             }
 
             return codecType;
@@ -175,8 +191,9 @@ namespace Lucene.Net.Codecs
         /// Gets a list of the available <see cref="Codec"/>s (by name).
         /// </summary>
         /// <returns>A <see cref="T:ICollection{string}"/> of <see cref="Codec"/>
names.</returns>
-        public ICollection<string> AvailableServices()
+        public virtual ICollection<string> AvailableServices()
         {
+            EnsureInitialized();
             return codecNameToTypeMap.Keys;
         }
     }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs b/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
index 91e5ac3..d5f0e75 100644
--- a/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
+++ b/src/Lucene.Net/Support/Codecs/DefaultDocValuesFormatFactory.cs
@@ -36,11 +36,11 @@ namespace Lucene.Net.Codecs
     ///     <item>subclass <see cref="DefaultDocValuesFormatFactory"/> and override
     ///         <see cref="DefaultDocValuesFormatFactory.GetDocValuesFormatType(string)"/>
so a type new type can be
     ///         supplied that is not in the <see cref="DefaultDocValuesFormatFactory.docValuesFormatNameToTypeMap"/>.</item>
+    ///     <item>subclass <see cref="DefaultDocValuesFormatFactory"/> to add
new or override the default <see cref="DocValuesFormat"/> 
+    ///         types by overriding <see cref="Initialize()"/> and calling <see
cref="PutPostingsFormatType(Type)"/>.</item>
     ///     <item>subclass <see cref="DefaultDocValuesFormatFactory"/> to scan
additional assemblies for <see cref="DocValuesFormat"/>
-    ///         subclasses in the constructor by calling <see cref="ScanForDocValuesFormats(Assembly)"/>.

+    ///         subclasses in by overriding <see cref="Initialize()"/> and calling
<see cref="ScanForPostingsFormats(Assembly)"/>. 
     ///         For performance reasons, the default behavior only loads Lucene.Net codecs.</item>
-    ///     <item>subclass <see cref="DefaultDocValuesFormatFactory"/> to add
override the default <see cref="DocValuesFormat"/> 
-    ///         types by calling <see cref="PutDocValuesFormatType(Type)"/>.</item>
     /// </list>
     /// <para/>
     /// To set the <see cref="IDocValuesFormatFactory"/>, call <see cref="DocValuesFormat.SetDocValuesFormatFactory(IDocValuesFormatFactory)"/>.
@@ -51,8 +51,18 @@ namespace Lucene.Net.Codecs
         // variable in the Codec class.
         private readonly IDictionary<string, Type> docValuesFormatNameToTypeMap = new
Dictionary<string, Type>();
         private readonly IDictionary<Type, DocValuesFormat> docValuesFormatInstanceCache
= new Dictionary<Type, DocValuesFormat>();
+        private object syncLock = new object();
 
-        public DefaultDocValuesFormatFactory()
+        /// <summary>
+        /// Initializes the doc values type cache with the known <see cref="DocValuesFormat"/>
types.
+        /// Override this method (and optionally call <c>base.Initialize()</c>)
to add your
+        /// own <see cref="DocValuesFormat"/> types by calling <see cref="PutDocValuesFormatType(Type)"/>

+        /// or <see cref="ScanForDocValuesFormats(Assembly)"/>.
+        /// <para/>
+        /// If two types have the same name by using the <see cref="DocValuesFormatNameAttribute"/>,
the
+        /// last one registered wins.
+        /// </summary>
+        protected override void Initialize()
         {
             ScanForDocValuesFormats(new Assembly[] {
                 typeof(Codec).GetTypeInfo().Assembly,
@@ -111,7 +121,7 @@ namespace Lucene.Net.Codecs
             }
             if (!typeof(DocValuesFormat).GetTypeInfo().IsAssignableFrom(docValuesFormat))
             {
-                throw new ArgumentException("System.Type passed dose not subclass DocValuesFormat.");
+                throw new ArgumentException("The supplied docValuesFormat does not subclass
DocValuesFormat.");
             }
 
             PutCodecTypeImpl(docValuesFormat);
@@ -130,8 +140,8 @@ namespace Lucene.Net.Codecs
         /// <returns>The <see cref="DocValuesFormat"/> instance.</returns>
         public virtual DocValuesFormat GetDocValuesFormat(string name)
         {
+            EnsureInitialized(); // Safety in case a subclass doesn't call it
             Type codecType = GetDocValuesFormatType(name);
-
             return GetDocValuesFormat(codecType);
         }
 
@@ -145,8 +155,14 @@ namespace Lucene.Net.Codecs
             DocValuesFormat instance;
             if (!docValuesFormatInstanceCache.TryGetValue(type, out instance))
             {
-                instance = (DocValuesFormat)Activator.CreateInstance(type, true);
-                docValuesFormatInstanceCache[type] = instance;
+                lock (syncLock)
+                {
+                    if (!docValuesFormatInstanceCache.TryGetValue(type, out instance))
+                    {
+                        instance = (DocValuesFormat)Activator.CreateInstance(type, IsFullyTrusted);
+                        docValuesFormatInstanceCache[type] = instance;
+                    }
+                }
             }
 
             return instance;
@@ -159,13 +175,13 @@ namespace Lucene.Net.Codecs
         /// <returns>The <see cref="DocValuesFormat"/> <see cref="Type"/>.</returns>
         protected virtual Type GetDocValuesFormatType(string name)
         {
+            EnsureInitialized();
             Type codecType;
-            docValuesFormatNameToTypeMap.TryGetValue(name, out codecType);
-            if (codecType == null)
+            if (!docValuesFormatNameToTypeMap.TryGetValue(name, out codecType) &&
codecType == null)
             {
                 throw new ArgumentException(string.Format("DocValuesFormat '{0}' cannot be
loaded. If the format is not " +
-                    "in a Lucene.Net assembly, you must subclass DefaultDocValuesFormatFactory
and call ScanForDocValuesFormats() with the " +
-                    "target assembly from the subclass constructor.", name));
+                    "in a Lucene.Net assembly, you must subclass DefaultDocValuesFormatFactory
and call PutDocValuesFormatType() " + 
+                    "or ScanForDocValuesFormats() from the Initialize() method.", name));
             }
 
             return codecType;
@@ -175,8 +191,9 @@ namespace Lucene.Net.Codecs
         /// Gets a list of the available <see cref="DocValuesFormat"/>s (by name).
         /// </summary>
         /// <returns>A <see cref="ICollection{string}"/> of <see cref="DocValuesFormat"/>
names.</returns>
-        public ICollection<string> AvailableServices()
+        public virtual ICollection<string> AvailableServices()
         {
+            EnsureInitialized();
             return docValuesFormatNameToTypeMap.Keys;
         }
     }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs b/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
index bbf7ecf..c1a3982 100644
--- a/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
+++ b/src/Lucene.Net/Support/Codecs/DefaultPostingsFormatFactory.cs
@@ -33,14 +33,14 @@ namespace Lucene.Net.Codecs
     ///         container can be used to supply the instances (lifetime should be singleton).
Note that you could 
     ///         alternately use the "named type" feature that many DI containers have to
supply the type based on name by 
     ///         overriding <see cref="GetDocValuesFormat(string)"/>.</item>
-    ///     <item>subclass <see cref="DefaultDPostingsFormatFactory"/> and override
+    ///     <item>subclass <see cref="DefaultPostingsFormatFactory"/> and override
     ///         <see cref="DefaultPostingsFormatFactory.GetPostingsFormatType(string)"/>
so a type new type can be
     ///         supplied that is not in the <see cref="DefaultPostingsFormatFactory.postingsFormatNameToTypeMap"/>.</item>
+    ///     <item>subclass <see cref="DefaultPostingsFormatFactory"/> to add
new or override the default <see cref="PostingsFormat"/> 
+    ///         types by overriding <see cref="Initialize()"/> and calling <see
cref="PutPostingsFormatType(Type)"/>.</item>
     ///     <item>subclass <see cref="DefaultPostingsFormatFactory"/> to scan
additional assemblies for <see cref="PostingsFormat"/>
-    ///         subclasses in the constructor by calling <see cref="ScanForPostingsFormats(Assembly)"/>.

+    ///         subclasses in by overriding <see cref="Initialize()"/> and calling
<see cref="ScanForPostingsFormats(Assembly)"/>. 
     ///         For performance reasons, the default behavior only loads Lucene.Net codecs.</item>
-    ///     <item>subclass <see cref="DefaultPostingsFormatFactory"/> to add
override the default <see cref="PostingsFormat"/> 
-    ///         types by calling <see cref="PutPostingsFormatType(Type)"/>.</item>
     /// </list>
     /// <para/>
     /// To set the <see cref="IPostingsFormatFactory"/>, call <see cref="DocValuesFormat.SetPostingsFormatFactory(IPostingsFormatFactory)"/>.
@@ -51,8 +51,18 @@ namespace Lucene.Net.Codecs
         // variable in the Codec class.
         private readonly IDictionary<string, Type> postingsFormatNameToTypeMap = new
Dictionary<string, Type>();
         private readonly IDictionary<Type, PostingsFormat> postingsFormatInstanceCache
= new Dictionary<Type, PostingsFormat>();
+        private object syncLock = new object();
 
-        public DefaultPostingsFormatFactory()
+        /// <summary>
+        /// Initializes the codec type cache with the known <see cref="PostingsFormat"/>
types.
+        /// Override this method (and optionally call <c>base.Initialize()</c>)
to add your
+        /// own <see cref="PostingsFormat"/> types by calling <see cref="PutDocPostingsFormatType(Type)"/>

+        /// or <see cref="ScanForPostingsFormats(Assembly)"/>.
+        /// <para/>
+        /// If two types have the same name by using the <see cref="PostingsFormatNameAttribute"/>,
the
+        /// last one registered wins.
+        /// </summary>
+        protected override void Initialize()
         {
             ScanForPostingsFormats(new Assembly[] {
                 typeof(Codec).GetTypeInfo().Assembly,
@@ -111,7 +121,7 @@ namespace Lucene.Net.Codecs
             }
             if (!typeof(PostingsFormat).GetTypeInfo().IsAssignableFrom(postingsFormat))
             {
-                throw new ArgumentException("System.Type passed dose not subclass PostingsFormat.");
+                throw new ArgumentException("The supplied postingsFormat does not subclass
PostingsFormat.");
             }
 
             PutPostingsFormatTypeImpl(postingsFormat);
@@ -130,8 +140,8 @@ namespace Lucene.Net.Codecs
         /// <returns>The <see cref="PostingsFormat"/> instance.</returns>
         public virtual PostingsFormat GetPostingsFormat(string name)
         {
+            EnsureInitialized(); // Safety in case a subclass doesn't call it
             Type codecType = GetPostingsFormatType(name);
-
             return GetPostingsFormat(codecType);
         }
 
@@ -145,8 +155,14 @@ namespace Lucene.Net.Codecs
             PostingsFormat instance;
             if (!postingsFormatInstanceCache.TryGetValue(type, out instance))
             {
-                instance = (PostingsFormat)Activator.CreateInstance(type, true);
-                postingsFormatInstanceCache[type] = instance;
+                lock (syncLock)
+                {
+                    if (!postingsFormatInstanceCache.TryGetValue(type, out instance))
+                    {
+                        instance = (PostingsFormat)Activator.CreateInstance(type, IsFullyTrusted);
+                        postingsFormatInstanceCache[type] = instance;
+                    }
+                }
             }
 
             return instance;
@@ -159,13 +175,13 @@ namespace Lucene.Net.Codecs
         /// <returns>The <see cref="PostingsFormat"/> <see cref="Type"/>.</returns>
         protected virtual Type GetPostingsFormatType(string name)
         {
+            EnsureInitialized();
             Type codecType;
-            postingsFormatNameToTypeMap.TryGetValue(name, out codecType);
-            if (codecType == null)
+            if (!postingsFormatNameToTypeMap.TryGetValue(name, out codecType) &&
codecType == null)
             {
                 throw new ArgumentException(string.Format("PostingsFormat '{0}' cannot be
loaded. If the format is not " +
-                    "in a Lucene.Net assembly, you must subclass DefaultPostingsFormatFactory
and call ScanForPostingsFormats() with the " +
-                    "target assembly from the subclass constructor.", name));
+                    "in a Lucene.Net assembly, you must subclass DefaultPostingsFormatFactory
and call PutPostingsFormatType() " + 
+                    "or ScanForPostingsFormats() from the Initialize() method.", name));
             }
 
             return codecType;
@@ -175,8 +191,9 @@ namespace Lucene.Net.Codecs
         /// Gets a list of the available <see cref="PostingsFormat"/>s (by name).
         /// </summary>
         /// <returns>A <see cref="ICollection{string}"/> of <see cref="PostingsFormat"/>
names.</returns>
-        public ICollection<string> AvailableServices()
+        public virtual ICollection<string> AvailableServices()
         {
+            EnsureInitialized();
             return postingsFormatNameToTypeMap.Keys;
         }
     }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/8a58d858/src/Lucene.Net/Support/Util/NamedServiceFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/Util/NamedServiceFactory.cs b/src/Lucene.Net/Support/Util/NamedServiceFactory.cs
index 0ca474b..03ac82c 100644
--- a/src/Lucene.Net/Support/Util/NamedServiceFactory.cs
+++ b/src/Lucene.Net/Support/Util/NamedServiceFactory.cs
@@ -1,6 +1,7 @@
 ´╗┐using System;
 using System.Linq;
 using System.Reflection;
+using System.Threading;
 
 namespace Lucene.Net.Util
 {
@@ -28,19 +29,30 @@ namespace Lucene.Net.Util
     public abstract class NamedServiceFactory<TService>
     {
         private static Assembly codecsAssembly = null;
+        private bool initialized = false;
+        private object initializationLock = new object();
+        private object initializationTarget; // Dummy variable required by LazyInitializer.EnsureInitialized
 
-        protected NamedServiceFactory()
+        /// <summary>
+        /// Ensures the <see cref="Initialize"/> method has been called since the
+        /// last application start. This method is thread-safe.
+        /// </summary>
+        protected void EnsureInitialized()
         {
-            // Attempt to load the SimpleTextCodec type. If it loads it will not be null,

-            // which means the assembly is referenced so we can load all of the named services
from that assembly.
-            Type simpleTextType = Type.GetType("Lucene.Net.Codecs.SimpleText.SimpleTextCodec,
Lucene.Net.Codecs");
-            if (simpleTextType != null)
+            LazyInitializer.EnsureInitialized(ref this.initializationTarget, ref this.initialized,
ref this.initializationLock, () =>
             {
-                codecsAssembly = simpleTextType.GetTypeInfo().Assembly;
-            }
+                Initialize();
+                return null;
+            });
         }
 
         /// <summary>
+        /// Initializes the dependencies of this factory (such as using Reflection to populate
the type cache).
+        /// </summary>
+        protected abstract void Initialize();
+
+
+        /// <summary>
         /// The Lucene.Net.Codecs assembly or <c>null</c> if the assembly is
not referenced
         /// in the host project.
         /// </summary>
@@ -48,6 +60,17 @@ namespace Lucene.Net.Util
         {
             get
             {
+                if (codecsAssembly == null)
+                {
+                    // Attempt to load the SimpleTextCodec type. If it loads it will not
be null, 
+                    // which means the assembly is referenced so we can load all of the named
services from that assembly.
+                    Type simpleTextType = Type.GetType("Lucene.Net.Codecs.SimpleText.SimpleTextCodec,
Lucene.Net.Codecs");
+                    if (simpleTextType != null)
+                    {
+                        codecsAssembly = simpleTextType.GetTypeInfo().Assembly;
+                    }
+                }
+
                 return codecsAssembly;
             }
         }
@@ -143,5 +166,20 @@ namespace Lucene.Net.Util
         {
             return ('a' <= c && c <= 'z') || ('A' <= c && c <=
'Z') || ('0' <= c && c <= '9');
         }
+
+        /// <summary>
+        /// Gets a value that indicates whether the current application domain executes with
full trust.
+        /// </summary>
+        protected bool IsFullyTrusted
+        {
+            get
+            {
+#if NETSTANDARD
+                return true; // Partial trust is obsolete
+#else
+                return AppDomain.CurrentDomain.IsFullyTrusted; // Partial trust support
+#endif
+            }
+        }
     }
 }


Mime
View raw message