Repository: JoshClose/CsvHelper

Issue:
New class level attributes are ignored, e.g. DelimiterAttribute
I have been experimenting with the new class level attributes for things like Delimiter, HasHeaderRecord, IgnoreBlankLines, etc. which were introduced in version 30.0.0. However, they don't appear to be working and they are ignored.
```c#
[Delimiter("|")]
[HasHeaderRecord(false)]
[IgnoreBlankLines(true)]
[TrimOptions(TrimOptions.Trim)]
public class Result
{
    [Index(0)]
    public string Type { get; set; }
    [Index(1)]
    public string Name { get; set; }
    [Index(3)]
    public string Ccy { get; set; }
}

//This works with settings in config file
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    Delimiter = ",",
    HasHeaderRecord = false,
    IgnoreBlankLines = true,
    TrimOptions = TrimOptions.Trim,
};

using (var reader = new StreamReader(file))
using (var csv = new CsvReader(reader, config))
{
    results.AddRange(csv.GetRecords<Result>());
}

//This does not work with settings as class level attributes on Result class
using (var reader = new StreamReader(file))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
    results.AddRange(csv.GetRecords<Result>());
}
```


Hints:
You need to either pass the `Type` into the constructor or call `ApplyAttributes`.

```cs
new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Result));
// or
new CsvConfiguration(CultureInfo.InvariantCulture).ApplyAttributes<Result>();
// or
new CsvConfiguration(CultureInfo.InvariantCulture).ApplyAttributes(typeof(Result));
```

Maybe it could be called automatically when passed into the `CsvReader` or `CsvWriter` constructor.
Great that works, thanks...
I ran into the same issue. Maybe [this page](https://joshclose.github.io/CsvHelper/examples/configuration/attributes/) needs to be amended to add the configuration block ?
Yes. I'll reopen this and change to documentation.

Patch:
diff --git a/src/CsvHelper.Website/input/examples/configuration/attributes/index.md b/src/CsvHelper.Website/input/examples/configuration/attributes/index.md
index 871798f14..41c588d41 100644
--- a/src/CsvHelper.Website/input/examples/configuration/attributes/index.md
+++ b/src/CsvHelper.Website/input/examples/configuration/attributes/index.md
@@ -5,9 +5,9 @@ Most of the configuration done via class maps can also be done using attributes.
 ###### Data
 
 ```
-Identifier,name,IsBool,Constant
-1,one,yes,a
-2,two,no,b
+Identifier||Amount2|IsBool|Constant
+1|1,234|1,234|yes|a
+2|1.234|1.234|no|b
 ```
 
 ###### Example
@@ -15,35 +15,54 @@ Identifier,name,IsBool,Constant
 ```cs
 void Main()
 {
+	CsvConfiguration config = CsvConfiguration.FromType<Foo>();
 	using (var reader = new StreamReader("path\\to\\file.csv"))
-	using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+	using (var csv = new CsvReader(reader, config))
 	{
-		csv.GetRecords<Foo>().ToList().Dump();
+		List<Foo> records = csv.GetRecords<Foo>().ToList();
+
+		// These all print "True"
+
+		Console.WriteLine(records.Count == 2);
+		Console.WriteLine(records[0].Id == 1);
+		Console.WriteLine(records[0].Amount == 1.234m);
+		Console.WriteLine(records[0].Amount2 == 1234);
+		Console.WriteLine(records[0].IsBool == true);
+		Console.WriteLine(records[0].Constant == "bar");
+		Console.WriteLine(records[0].Optional == null);
+		Console.WriteLine(records[0].Ignored == null);
+
+		Console.WriteLine(records[1].Amount == 1234);
+		Console.WriteLine(records[1].Amount2 == 1.234m);
+
 	}
 }
 
-[Delimiter(",")]
-[CultureInfo("")]  // Set CultureInfo to InvariantCulture
+[Delimiter("|")]
+[CultureInfo("de-DE")]
 public class Foo
 {
 	[Name("Identifier")]
 	public int Id { get; set; }
-	
+
 	[Index(1)]
-	public string Name { get; set; }
+	public decimal Amount { get; set; }
 	
+	[CultureInfo("InvariantCulture")]
+	public decimal Amount2 { get; set; }
+
 	[BooleanTrueValues("yes")]
 	[BooleanFalseValues("no")]
 	public bool IsBool { get; set; }
-	
+
 	[Constant("bar")]
 	public string Constant { get; set; }
-	
+
 	[Optional]
 	public string Optional { get; set; }
-	
+
 	[Ignore]
-	public string Ignored { get; set; }	
+	public string Ignored { get; set; }
 }
 
 ```
diff --git a/src/CsvHelper/Configuration/Attributes/AllowCommentsAttribute.cs b/src/CsvHelper/Configuration/Attributes/AllowCommentsAttribute.cs
index 1490cc92b..d847026e3 100644
--- a/src/CsvHelper/Configuration/Attributes/AllowCommentsAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/AllowCommentsAttribute.cs
@@ -7,21 +7,21 @@
 namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
-	/// A value indicating if comments are allowed.
+	/// A value indicating whether comments are allowed.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class AllowCommentsAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
-		/// Gets a value indicating if comments are allowed.
+		/// Gets a value indicating whether comments are allowed.
 		/// </summary>
 		public bool AllowComments { get; private set; }
 
 		/// <summary>
-		/// A value indicating if comments are allowed.
+		/// A value indicating whether comments are allowed.
 		/// </summary>
-		/// <param name="allowComments">The value indicating id comments are allowed.</param>
-		public AllowCommentsAttribute(bool allowComments)
+		/// <param name="allowComments">The value indicating whether comments are allowed.</param>
+		public AllowCommentsAttribute(bool allowComments = true)
 		{
 			AllowComments = allowComments;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/CacheFieldsAttribute.cs b/src/CsvHelper/Configuration/Attributes/CacheFieldsAttribute.cs
index 1f6b85957..1bf165690 100644
--- a/src/CsvHelper/Configuration/Attributes/CacheFieldsAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/CacheFieldsAttribute.cs
@@ -8,7 +8,6 @@ namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
 	/// Cache fields that are created when parsing.
-	/// Default is false.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class CacheFieldsAttribute : Attribute, IClassMapper
@@ -22,7 +21,7 @@ public class CacheFieldsAttribute : Attribute, IClassMapper
 		/// Cache fields that are created when parsing.
 		/// </summary>
 		/// <param name="cacheFields"></param>
-		public CacheFieldsAttribute(bool cacheFields)
+		public CacheFieldsAttribute(bool cacheFields = true)
 		{
 			CacheFields = cacheFields;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/CountBytesAttribute.cs b/src/CsvHelper/Configuration/Attributes/CountBytesAttribute.cs
index 165784ef4..92bd18c56 100644
--- a/src/CsvHelper/Configuration/Attributes/CountBytesAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/CountBytesAttribute.cs
@@ -9,7 +9,7 @@ namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
 	/// A value indicating whether the number of bytes should
-	/// be counted while parsing. Default is false. This will slow down parsing
+	/// be counted while parsing. This will slow down parsing
 	/// because it needs to get the byte count of every char for the given encoding.
 	/// The <see cref="Encoding"/> needs to be set correctly for this to be accurate.
 	/// </summary>
@@ -18,7 +18,7 @@ public class CountBytesAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
 		/// A value indicating whether the number of bytes should
-		/// be counted while parsing. Default is false. This will slow down parsing
+		/// be counted while parsing. This will slow down parsing
 		/// because it needs to get the byte count of every char for the given encoding.
 		/// The <see cref="Encoding"/> needs to be set correctly for this to be accurate.
 		/// </summary>
@@ -26,12 +26,12 @@ public class CountBytesAttribute : Attribute, IClassMapper
 
 		/// <summary>
 		/// A value indicating whether the number of bytes should
-		/// be counted while parsing. Default is false. This will slow down parsing
+		/// be counted while parsing. This will slow down parsing
 		/// because it needs to get the byte count of every char for the given encoding.
 		/// The <see cref="Encoding"/> needs to be set correctly for this to be accurate.
 		/// </summary>
 		/// <param name="countBytes"></param>
-		public CountBytesAttribute(bool countBytes)
+		public CountBytesAttribute(bool countBytes = true)
 		{
 			CountBytes = countBytes;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/CultureInfoAttribute.cs b/src/CsvHelper/Configuration/Attributes/CultureInfoAttribute.cs
index 3ab637f66..5b0809615 100644
--- a/src/CsvHelper/Configuration/Attributes/CultureInfoAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/CultureInfoAttribute.cs
@@ -8,11 +8,12 @@
 namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
-	/// The <see cref="CultureInfo"/> used when type converting.
-	/// This will override the global <see cref="CsvConfiguration.CultureInfo"/>
-	/// setting. Or set the same if the attribute is specified on class level.
+	/// When applied to a member, specifies the <see cref="System.Globalization.CultureInfo"/>
+	/// used when type converting the member. When applied to a type, the value of
+	/// <see cref="CsvConfiguration.CultureInfo"/> in the <see cref="CsvConfiguration"/>
+	/// returned by <see cref="CsvConfiguration.FromType{T}()"/>
 	/// </summary>
-	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class CultureInfoAttribute : Attribute, IMemberMapper, IParameterMapper
 	{
 		/// <summary>
@@ -20,15 +21,32 @@ public class CultureInfoAttribute : Attribute, IMemberMapper, IParameterMapper
 		/// </summary>
 		public CultureInfo CultureInfo { get; private set; }
 
-		/// <summary>
-		/// The <see cref="CultureInfo"/> used when type converting.
-		/// This will override the global <see cref="CsvConfiguration.CultureInfo"/>
-		/// setting. Or set the same if the attribute is specified on class level.
-		/// </summary>
-		/// <param name="culture">The culture.</param>
-		public CultureInfoAttribute(string culture)
+		/// <summary><inheritdoc cref="CultureInfoAttribute"/></summary>
+		/// <param name="name">
+		/// The name of a culture (case insensitive), or the literal values <c>"InvariantCulture"</c>,
+		/// <c>"CurrentCulture"</c>, <c>"CurrentUICulture"</c>, <c>"InstalledUICulture"</c> to use the
+		/// corresponding static properties on <see cref="System.Globalization.CultureInfo"/>.
+		/// </param>
+		public CultureInfoAttribute(string name)
 		{
-			CultureInfo = CultureInfo.GetCultureInfo(culture);
+			switch(name)
+			{
+				case nameof(CultureInfo.InvariantCulture):
+					CultureInfo = CultureInfo.InvariantCulture;
+					break;
+				case nameof(CultureInfo.CurrentCulture):
+					CultureInfo = CultureInfo.CurrentCulture;
+					break;
+				case nameof(CultureInfo.CurrentUICulture):
+					CultureInfo = CultureInfo.CurrentUICulture;
+					break;
+				case nameof(CultureInfo.InstalledUICulture):
+					CultureInfo = CultureInfo.InstalledUICulture;
+					break;
+				default:
+					CultureInfo = CultureInfo.GetCultureInfo(name);
+					break;
+			}
 		}
 
 		/// <inheritdoc />
diff --git a/src/CsvHelper/Configuration/Attributes/DetectColumnCountChangesAttribute.cs b/src/CsvHelper/Configuration/Attributes/DetectColumnCountChangesAttribute.cs
index f31aaf84a..68485def1 100644
--- a/src/CsvHelper/Configuration/Attributes/DetectColumnCountChangesAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/DetectColumnCountChangesAttribute.cs
@@ -8,7 +8,7 @@ namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
 	/// A value indicating whether changes in the column
-	/// count should be detected. If true, a <see cref="BadDataException"/>
+	/// count should be detected. If <see langword="true"/>, a <see cref="BadDataException"/>
 	/// will be thrown if a different column count is detected.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
@@ -16,17 +16,17 @@ public class DetectColumnCountChangesAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
 		/// A value indicating whether changes in the column
-		/// count should be detected. If true, a <see cref="BadDataException"/>
+		/// count should be detected. If <see langword="true"/>, a <see cref="BadDataException"/>
 		/// will be thrown if a different column count is detected.
 		/// </summary>
 		public bool DetectColumnCountChanges { get; private set; }
 
 		/// <summary>
 		/// A value indicating whether changes in the column
-		/// count should be detected. If true, a <see cref="BadDataException"/>
+		/// count should be detected. If <see langword="true"/>, a <see cref="BadDataException"/>
 		/// will be thrown if a different column count is detected.
 		/// </summary>
-		public DetectColumnCountChangesAttribute(bool detectColumnCountChanges)
+		public DetectColumnCountChangesAttribute(bool detectColumnCountChanges = true)
 		{
 			DetectColumnCountChanges = detectColumnCountChanges;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/DetectDelimiterAttribute.cs b/src/CsvHelper/Configuration/Attributes/DetectDelimiterAttribute.cs
index 2c7da4563..6cfd2043d 100644
--- a/src/CsvHelper/Configuration/Attributes/DetectDelimiterAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/DetectDelimiterAttribute.cs
@@ -8,7 +8,6 @@ namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
 	/// Detect the delimiter instead of using the delimiter from configuration.
-	/// Default is <c>false</c>.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class DetectDelimiterAttribute : Attribute, IClassMapper
@@ -21,7 +20,7 @@ public class DetectDelimiterAttribute : Attribute, IClassMapper
 		/// <summary>
 		/// Detect the delimiter instead of using the delimiter from configuration.
 		/// </summary>
-		public DetectDelimiterAttribute(bool detectDelimiter)
+		public DetectDelimiterAttribute(bool detectDelimiter = true)
 		{
 			DetectDelimiter = detectDelimiter;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/EncodingAttribute.cs b/src/CsvHelper/Configuration/Attributes/EncodingAttribute.cs
index ee378ba94..d24e251fc 100644
--- a/src/CsvHelper/Configuration/Attributes/EncodingAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/EncodingAttribute.cs
@@ -18,14 +18,23 @@ public class EncodingAttribute : Attribute, IClassMapper
         /// </summary>
         public Encoding Encoding { get; private set; }
 
-        /// <summary>
-        /// The encoding used when counting bytes.
-        /// </summary>
-        /// <param name="encoding">The encoding.</param>
-        public EncodingAttribute(string encoding)
+		/// <summary>
+		/// The encoding used when counting bytes.
+		/// </summary>
+		/// <param name="name"><inheritdoc cref="Encoding.GetEncoding(string)"/></param>
+		public EncodingAttribute(string name)
         {
-            Encoding = Encoding.GetEncoding(encoding);
-        }
+            Encoding = Encoding.GetEncoding(name);
+		}
+
+		/// <summary>
+		/// The encoding used when counting bytes.
+		/// </summary>
+		/// <param name="codepage"><inheritdoc cref="Encoding.GetEncoding(int)"/></param>
+		public EncodingAttribute(int codepage)
+		{
+			Encoding = Encoding.GetEncoding(codepage);
+		}
 
 		/// <inheritdoc />
 		public void ApplyTo(CsvConfiguration configuration)
diff --git a/src/CsvHelper/Configuration/Attributes/EscapeAttribute.cs b/src/CsvHelper/Configuration/Attributes/EscapeAttribute.cs
index 0d20d504d..9346484c8 100644
--- a/src/CsvHelper/Configuration/Attributes/EscapeAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/EscapeAttribute.cs
@@ -9,7 +9,7 @@ namespace CsvHelper.Configuration.Attributes
     /// <summary>
     /// The escape character used to escape a quote inside a field.
     /// </summary>
-    [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
     public class EscapeAttribute : Attribute, IClassMapper
     {
         /// <summary>
@@ -21,7 +21,7 @@ public class EscapeAttribute : Attribute, IClassMapper
         /// The escape character used to escape a quote inside a field.
         /// </summary>
         /// <param name="escape">The escape character.</param>
-        public EscapeAttribute( char escape )
+        public EscapeAttribute(char escape)
         {
             Escape = escape;
         }
diff --git a/src/CsvHelper/Configuration/Attributes/ExceptionMessagesContainRawDataAttribute.cs b/src/CsvHelper/Configuration/Attributes/ExceptionMessagesContainRawDataAttribute.cs
index 2cb960824..7d754080f 100644
--- a/src/CsvHelper/Configuration/Attributes/ExceptionMessagesContainRawDataAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/ExceptionMessagesContainRawDataAttribute.cs
@@ -7,25 +7,23 @@
 namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
-	/// A value indicating if exception messages contain raw CSV data.
-	/// <c>true</c> if exception contain raw CSV data, otherwise <c>false</c>.
-	/// Default is <c>true</c>.
+	/// A value indicating whether exception messages contain raw CSV data.
+	/// <see langword="true"/> if exceptions contain raw CSV data, otherwise <see langword="false"/>.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class ExceptionMessagesContainRawDataAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
-		/// A value indicating if exception messages contain raw CSV data.
-		/// <c>true</c> if exception contain raw CSV data, otherwise <c>false</c>.
+		/// A value indicating whether exception messages contain raw CSV data.
+		/// <see langword="true"/> if exceptions contain raw CSV data, otherwise <see langword="false"/>.
 		/// </summary>
 		public bool ExceptionMessagesContainRawData { get; private set; }
 
 		/// <summary>
-		/// A value indicating if exception messages contain raw CSV data.
-		/// <c>true</c> if exception contain raw CSV data, otherwise <c>false</c>.
+		/// A value indicating whether exception messages contain raw CSV data.
+		/// <see langword="true"/> if exceptions contain raw CSV data, otherwise <see langword="false"/>.
 		/// </summary>
-		/// <param name="exceptionMessagesContainRawData"></param>
-		public ExceptionMessagesContainRawDataAttribute(bool exceptionMessagesContainRawData)
+		public ExceptionMessagesContainRawDataAttribute(bool exceptionMessagesContainRawData = true)
 		{
 			ExceptionMessagesContainRawData = exceptionMessagesContainRawData;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/HasHeaderRecordAttribute.cs b/src/CsvHelper/Configuration/Attributes/HasHeaderRecordAttribute.cs
index b0d93ae86..4c2f0252f 100644
--- a/src/CsvHelper/Configuration/Attributes/HasHeaderRecordAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/HasHeaderRecordAttribute.cs
@@ -7,21 +7,21 @@
 namespace CsvHelper.Configuration.Attributes
 {
     /// <summary>
-    /// A value indicating if the CSV file has a header record.
+    /// A value indicating whether the CSV file has a header record.
     /// </summary>
-    [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
     public class HasHeaderRecordAttribute : Attribute, IClassMapper
     {
         /// <summary>
-        /// Gets a value indicating if the CSV file has a header record.
+        /// Gets a value indicating whether the CSV file has a header record.
         /// </summary>
         public bool HasHeaderRecord { get; private set; }
 
         /// <summary>
-        /// A value indicating if the CSV file has a header record.
+        /// A value indicating whether the CSV file has a header record.
         /// </summary>
-        /// <param name="hasHeaderRecord">A value indicating if the CSV file has a header record.</param>
-        public HasHeaderRecordAttribute( bool hasHeaderRecord )
+        /// <param name="hasHeaderRecord">A value indicating whether the CSV file has a header record.</param>
+        public HasHeaderRecordAttribute(bool hasHeaderRecord = true)
         {
             HasHeaderRecord = hasHeaderRecord;
         }
diff --git a/src/CsvHelper/Configuration/Attributes/HeaderPrefixAttribute.cs b/src/CsvHelper/Configuration/Attributes/HeaderPrefixAttribute.cs
index 7c28ec79f..b2f30e332 100644
--- a/src/CsvHelper/Configuration/Attributes/HeaderPrefixAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/HeaderPrefixAttribute.cs
@@ -18,7 +18,7 @@ public class HeaderPrefixAttribute : Attribute, IMemberReferenceMapper, IParamet
 		public string? Prefix { get; private set; }
 
 		/// <summary>
-		/// Gets a value indicating if the prefix should inherit parent prefixes.
+		/// Gets a value indicating whether the prefix should inherit parent prefixes.
 		/// </summary>
 		public bool Inherit { get; private set; }
 
diff --git a/src/CsvHelper/Configuration/Attributes/IgnoreBlankLinesAttribute.cs b/src/CsvHelper/Configuration/Attributes/IgnoreBlankLinesAttribute.cs
index c2705686e..51f2f4f9d 100644
--- a/src/CsvHelper/Configuration/Attributes/IgnoreBlankLinesAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/IgnoreBlankLinesAttribute.cs
@@ -7,21 +7,20 @@
 namespace CsvHelper.Configuration.Attributes
 {
     /// <summary>
-    /// A value indicating if blank lines should be ignored when reading.
+    /// A value indicating whether blank lines should be ignored when reading.
     /// </summary>
-    [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
     public class IgnoreBlankLinesAttribute : Attribute, IClassMapper
     {
         /// <summary>
-        /// Gets a value indicating if blank lines should be ignored when reading.
+        /// Gets a value indicating whether blank lines should be ignored when reading.
         /// </summary>
         public bool IgnoreBlankLines { get; private set; }
 
         /// <summary>
-        /// A value indicating if blank lines should be ignored when reading.
+        /// A value indicating whether blank lines should be ignored when reading.
         /// </summary>
-        /// <param name="ignoreBlankLines">The Ignore Blank Lines Flag.</param>
-        public IgnoreBlankLinesAttribute( bool ignoreBlankLines )
+        public IgnoreBlankLinesAttribute(bool ignoreBlankLines = true)
         {
             IgnoreBlankLines = ignoreBlankLines;
         }
diff --git a/src/CsvHelper/Configuration/Attributes/IgnoreReferencesAttribute.cs b/src/CsvHelper/Configuration/Attributes/IgnoreReferencesAttribute.cs
index 05e7b0e52..86eef9ff6 100644
--- a/src/CsvHelper/Configuration/Attributes/IgnoreReferencesAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/IgnoreReferencesAttribute.cs
@@ -8,26 +8,25 @@ namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
 	/// Gets a value indicating whether references
-	/// should be ignored when auto mapping. <c>true</c> to ignore
-	/// references, otherwise <c>false</c>. Default is false.
+	/// should be ignored when auto mapping. <see langword="true"/> to ignore
+	/// references, otherwise <see langword="false"/>.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class IgnoreReferencesAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
 		/// Gets a value indicating whether references
-		/// should be ignored when auto mapping. <c>true</c> to ignore
-		/// references, otherwise <c>false</c>. Default is false.
+		/// should be ignored when auto mapping. <see langword="true"/> to ignore
+		/// references, otherwise <see langword="false"/>.
 		/// </summary>
 		public bool IgnoreReferences { get; private set; }
 
 		/// <summary>
 		/// Gets a value indicating whether references
-		/// should be ignored when auto mapping. <c>true</c> to ignore
-		/// references, otherwise <c>false</c>. Default is false.
+		/// should be ignored when auto mapping. <see langword="true"/> to ignore
+		/// references, otherwise <see langword="false"/>.
 		/// </summary>
-		/// <param name="ignoreReferences">Ignore references value.</param>
-		public IgnoreReferencesAttribute(bool ignoreReferences)
+		public IgnoreReferencesAttribute(bool ignoreReferences = true)
 		{
 			IgnoreReferences = ignoreReferences;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/IncludePrivateMembersAttribute.cs b/src/CsvHelper/Configuration/Attributes/IncludePrivateMembersAttribute.cs
index 92c7c1b2a..55e27d5f9 100644
--- a/src/CsvHelper/Configuration/Attributes/IncludePrivateMembersAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/IncludePrivateMembersAttribute.cs
@@ -7,21 +7,20 @@
 namespace CsvHelper.Configuration.Attributes
 {
     /// <summary>
-    /// A value indicating if private member should be read from and written to.
+    /// A value indicating whether private members should be read from and written to.
     /// </summary>
-    [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
     public class IncludePrivateMembersAttribute : Attribute, IClassMapper
     {
         /// <summary>
-        /// Gets a value indicating if private member should be read from and written to.
+        /// Gets a value indicating whether private members should be read from and written to.
         /// </summary>
         public bool IncludePrivateMembers { get; private set; }
 
         /// <summary>
-        /// A value indicating if private member should be read from and written to.
+        /// A value indicating whether private members should be read from and written to.
         /// </summary>
-        /// <param name="includePrivateMembers">The Include Private Members Flag.</param>
-        public IncludePrivateMembersAttribute( bool includePrivateMembers )
+        public IncludePrivateMembersAttribute(bool includePrivateMembers = true)
         {
             IncludePrivateMembers = includePrivateMembers;
         }
diff --git a/src/CsvHelper/Configuration/Attributes/IndexAttribute.cs b/src/CsvHelper/Configuration/Attributes/IndexAttribute.cs
index 6694aed12..3db1a4241 100644
--- a/src/CsvHelper/Configuration/Attributes/IndexAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/IndexAttribute.cs
@@ -12,7 +12,7 @@ namespace CsvHelper.Configuration.Attributes
 	/// will be written in the order of the field
 	/// indexes.
 	/// </summary>
-	[AttributeUsage( AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true )]
+	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
 	public class IndexAttribute : Attribute, IMemberMapper, IParameterMapper
 	{
 		/// <summary>
@@ -33,7 +33,7 @@ public class IndexAttribute : Attribute, IMemberMapper, IParameterMapper
 		/// </summary>
 		/// <param name="index">The index.</param>
 		/// <param name="indexEnd">The index end.</param>
-		public IndexAttribute( int index, int indexEnd = -1 )
+		public IndexAttribute(int index, int indexEnd = -1)
 		{
 			Index = index;
 			IndexEnd = indexEnd;
diff --git a/src/CsvHelper/Configuration/Attributes/InjectionCharactersAttribute.cs b/src/CsvHelper/Configuration/Attributes/InjectionCharactersAttribute.cs
index 66f696468..b1ea84a5d 100644
--- a/src/CsvHelper/Configuration/Attributes/InjectionCharactersAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/InjectionCharactersAttribute.cs
@@ -11,6 +11,7 @@ namespace CsvHelper.Configuration.Attributes
 	/// <summary>
 	/// Gets the characters that are used for injection attacks.
 	/// </summary>
+	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class InjectionCharactersAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
diff --git a/src/CsvHelper/Configuration/Attributes/LineBreakInQuotedFieldIsBadDataAttribute.cs b/src/CsvHelper/Configuration/Attributes/LineBreakInQuotedFieldIsBadDataAttribute.cs
index db95cbcd2..cea3934e1 100644
--- a/src/CsvHelper/Configuration/Attributes/LineBreakInQuotedFieldIsBadDataAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/LineBreakInQuotedFieldIsBadDataAttribute.cs
@@ -7,25 +7,23 @@
 namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
-	/// A value indicating if a line break found in a quote field should
-	/// be considered bad data. <c>true</c> to consider a line break bad data, otherwise <c>false</c>.
-	/// Defaults to false.
+	/// A value indicating whether a line break found in a quote field should
+	/// be considered bad data. <see langword="true"/> to consider a line break bad data, otherwise <see langword="false"/>.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class LineBreakInQuotedFieldIsBadDataAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
-		/// A value indicating if a line break found in a quote field should
-		/// be considered bad data. <c>true</c> to consider a line break bad data, otherwise <c>false</c>.
+		/// A value indicating whether a line break found in a quote field should
+		/// be considered bad data. <see langword="true"/> to consider a line break bad data, otherwise <see langword="false"/>.
 		/// </summary>
 		public bool LineBreakInQuotedFieldIsBadData { get; private set; }
 
 		/// <summary>
-		/// A value indicating if a line break found in a quote field should
-		/// be considered bad data. <c>true</c> to consider a line break bad data, otherwise <c>false</c>.
+		/// A value indicating whether a line break found in a quote field should
+		/// be considered bad data. <see langword="true"/> to consider a line break bad data, otherwise <see langword="false"/>.
 		/// </summary>
-		/// <param name="lineBreakInQuotedFieldIsBadData"></param>
-		public LineBreakInQuotedFieldIsBadDataAttribute(bool lineBreakInQuotedFieldIsBadData)
+		public LineBreakInQuotedFieldIsBadDataAttribute(bool lineBreakInQuotedFieldIsBadData = true)
 		{
 			LineBreakInQuotedFieldIsBadData = lineBreakInQuotedFieldIsBadData;
 		}
diff --git a/src/CsvHelper/Configuration/Attributes/QuoteAttribute.cs b/src/CsvHelper/Configuration/Attributes/QuoteAttribute.cs
index 93b5887f2..cf66834a2 100644
--- a/src/CsvHelper/Configuration/Attributes/QuoteAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/QuoteAttribute.cs
@@ -9,7 +9,7 @@ namespace CsvHelper.Configuration.Attributes
     /// <summary>
     /// The character used to quote fields.
     /// </summary>
-    [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
     public class QuoteAttribute : Attribute, IClassMapper
     {
         /// <summary>
@@ -21,7 +21,7 @@ public class QuoteAttribute : Attribute, IClassMapper
         /// The character used to quote fields.
         /// </summary>
         /// <param name="quote">The quote character.</param>
-        public QuoteAttribute( char quote )
+        public QuoteAttribute(char quote)
         {
             Quote = quote;
         }
diff --git a/src/CsvHelper/Configuration/Attributes/TrimOptionsAttribute.cs b/src/CsvHelper/Configuration/Attributes/TrimOptionsAttribute.cs
index 1b2f645be..ca8abd52a 100644
--- a/src/CsvHelper/Configuration/Attributes/TrimOptionsAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/TrimOptionsAttribute.cs
@@ -9,7 +9,7 @@ namespace CsvHelper.Configuration.Attributes
     /// <summary>
     /// The fields trimming options.
     /// </summary>
-    [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
     public class TrimOptionsAttribute : Attribute, IClassMapper
     {
         /// <summary>
@@ -21,7 +21,7 @@ public class TrimOptionsAttribute : Attribute, IClassMapper
         /// The fields trimming options.
         /// </summary>
         /// <param name="trimOptions">The TrimOptions.</param>
-        public TrimOptionsAttribute( TrimOptions trimOptions )
+        public TrimOptionsAttribute(TrimOptions trimOptions)
         {
             TrimOptions = trimOptions;
         }
diff --git a/src/CsvHelper/Configuration/Attributes/UseNewObjectForNullReferenceMembersAttribute.cs b/src/CsvHelper/Configuration/Attributes/UseNewObjectForNullReferenceMembersAttribute.cs
index 6bfbf3763..d605b7551 100644
--- a/src/CsvHelper/Configuration/Attributes/UseNewObjectForNullReferenceMembersAttribute.cs
+++ b/src/CsvHelper/Configuration/Attributes/UseNewObjectForNullReferenceMembersAttribute.cs
@@ -7,33 +7,32 @@
 namespace CsvHelper.Configuration.Attributes
 {
 	/// <summary>
-	/// Gets a value indicating that during writing if a new 
-	/// object should be created when a reference member is null.
-	/// True to create a new object and use it's defaults for the
-	/// fields, or false to leave the fields empty for all the
-	/// reference member's member.
+	/// Gets a value indicating that during writing whether a new 
+	/// object should be created when a reference member is <see langword="null"/>.
+	/// <see langword="true"/> to create a new object and use its defaults for the
+	/// fields, or <see langword="false"/> to leave the fields empty for all the
+	/// reference member's members.
 	/// </summary>
 	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
 	public class UseNewObjectForNullReferenceMembersAttribute : Attribute, IClassMapper
 	{
 		/// <summary>
-		/// Gets a value indicating that during writing if a new 
-		/// object should be created when a reference member is null.
-		/// True to create a new object and use it's defaults for the
-		/// fields, or false to leave the fields empty for all the
-		/// reference member's member.
+		/// Gets a value indicating that during writing whether a new 
+		/// object should be created when a reference member is <see langword="null"/>.
+		/// <see langword="true"/> to create a new object and use its defaults for the
+		/// fields, or <see langword="false"/> to leave the fields empty for all the
+		/// reference member's members.
 		/// </summary>
 		public bool UseNewObjectForNullReferenceMembers { get; private set; }
 
 		/// <summary>
-		/// Gets a value indicating that during writing if a new 
-		/// object should be created when a reference member is null.
-		/// True to create a new object and use it's defaults for the
-		/// fields, or false to leave the fields empty for all the
-		/// reference member's member.
+		/// Gets a value indicating that during writing whether a new 
+		/// object should be created when a reference member is <see langword="null"/>.
+		/// <see langword="true"/> to create a new object and use its defaults for the
+		/// fields, or <see langword="false"/> to leave the fields empty for all the
+		/// reference member's members.
 		/// </summary>
-		/// <param name="useNewObjectForNullReferenceMembers">The value.</param>
-		public UseNewObjectForNullReferenceMembersAttribute(bool useNewObjectForNullReferenceMembers)
+		public UseNewObjectForNullReferenceMembersAttribute(bool useNewObjectForNullReferenceMembers = true)
 		{
 			UseNewObjectForNullReferenceMembers = useNewObjectForNullReferenceMembers;
 		}
diff --git a/src/CsvHelper/Configuration/CsvConfiguration.cs b/src/CsvHelper/Configuration/CsvConfiguration.cs
index 51636a28e..5c92a50f5 100644
--- a/src/CsvHelper/Configuration/CsvConfiguration.cs
+++ b/src/CsvHelper/Configuration/CsvConfiguration.cs
@@ -11,7 +11,6 @@
 using System.Text;
 using CsvHelper.Configuration.Attributes;
 using CsvHelper.Delegates;
-using CsvHelper.TypeConversion;
 
 namespace CsvHelper.Configuration
 {
@@ -165,21 +164,14 @@ public virtual string NewLine
 		/// <summary>
 		/// Initializes a new instance of the <see cref="CsvConfiguration"/> class
 		/// using the given <see cref="System.Globalization.CultureInfo"/>. Since <see cref="Delimiter"/>
-		/// uses <see cref="CultureInfo"/> for it's default, the given <see cref="System.Globalization.CultureInfo"/>
+		/// uses <see cref="CultureInfo"/> for its default, the given <see cref="System.Globalization.CultureInfo"/>
 		/// will be used instead.
 		/// </summary>
 		/// <param name="cultureInfo">The culture information.</param>
-		/// <param name="attributesType">The type that contains the configuration attributes.
-		/// This will call <see cref="ApplyAttributes(Type)"/> automatically.</param>
-		public CsvConfiguration(CultureInfo cultureInfo, Type? attributesType = null)
+		public CsvConfiguration(CultureInfo cultureInfo)
 		{
 			CultureInfo = cultureInfo;
 			Delimiter = cultureInfo.TextInfo.ListSeparator;
-
-			if (attributesType != null)
-			{
-				ApplyAttributes(attributesType);
-			}
 		}
 
 		/// <summary>
@@ -236,5 +228,87 @@ public CsvConfiguration ApplyAttributes(Type type)
 
 			return this;
 		}
+
+		/// <summary>
+		/// Creates a <see cref="CsvConfiguration"/> instance configured using CsvHelper attributes applied
+		/// to <typeparamref name="T"/> at the type-level. This method requires <typeparamref name="T"/> to
+		/// be annotated with <see cref="CultureInfoAttribute"/> (or to sub-class a type which is).
+		/// </summary>
+		/// <typeparam name="T">
+		/// The type whose attributes should be used to configure the <see cref="CsvConfiguration"/> instance.
+		/// This is normally the type you are intending to map for reading and writing.
+		/// </typeparam>
+		/// <returns>A new <see cref="CsvConfiguration"/> instance configured with attributes applied to <typeparamref name="T"/>.</returns>
+		/// <remarks>
+		/// CsvHelper attributes applied to members and parameters do not influence the return value of this method.
+		/// Such attributes do not define values which are used in <see cref="CsvConfiguration"/> and instead influence
+		/// the maps which are built and used during reading and writing. See <see cref="MemberMap"/> and <see cref="ParameterMap"/>.
+		/// </remarks>
+		/// <exception cref="ConfigurationException">If <typeparamref name="T"/> is not annotated with <see cref="CultureInfoAttribute"/>.</exception>
+		/// <exception cref="ArgumentNullException">If the argument to the <see cref="CultureInfoAttribute"/> is <see langword="null"/>.</exception>
+		/// <exception cref="CultureNotFoundException">If the argument to the <see cref="CultureInfoAttribute"/> does not specify a supported culture.</exception>
+		public static CsvConfiguration FromType<T>()
+		{
+			return FromType(typeof(T));
+		}
+
+		/// <summary>
+		/// Creates a <see cref="CsvConfiguration"/> instance configured using <paramref name="cultureInfo"/>
+		/// and CsvHelper attributes applied to <typeparamref name="T"/> at the type-level.
+		/// This method ignores any <see cref="CultureInfoAttribute"/> applied to <typeparamref name="T"/>.
+		/// </summary>
+		/// <typeparam name="T"><inheritdoc cref="FromType{T}()"/></typeparam>
+		/// <param name="cultureInfo">The <see cref="CultureInfo"/> to configure the returned <see cref="CsvConfiguration"/> with.</param>
+		/// <returns>A new <see cref="CsvConfiguration"/> instance configured with <paramref name="cultureInfo"/> and attributes applied to <typeparamref name="T"/>.</returns>
+		/// <remarks><inheritdoc cref="FromType{T}()"/></remarks>
+		public static CsvConfiguration FromType<T>(CultureInfo cultureInfo)
+		{
+			return FromType(typeof(T), cultureInfo);
+		}
+
+		/// <summary>
+		/// Creates a <see cref="CsvConfiguration"/> instance configured using CsvHelper attributes applied
+		/// to <paramref name="type"/> at the type-level. This method requires <paramref name="type"/> to
+		/// be annotated with <see cref="CultureInfoAttribute"/> (or to sub-class a type which is).
+		/// </summary>
+		/// <param name="type"><inheritdoc cref="FromType{T}()" path="/typeparam"/></param>
+		/// <returns>A new <see cref="CsvConfiguration"/> instance configured with attributes applied to <paramref name="type"/>.</returns>
+		/// <remarks>
+		/// CsvHelper attributes applied to members and parameters do not influence the return value of this method.
+		/// Such attributes do not define values which are used in <see cref="CsvConfiguration"/> and instead influence
+		/// the maps which are built and used during reading and writing. See <see cref="MemberMap"/> and <see cref="ParameterMap"/>.
+		/// </remarks>
+		/// <exception cref="ConfigurationException">If <paramref name="type"/> is not annotated with <see cref="CultureInfoAttribute"/>.</exception>
+		/// <exception cref="ArgumentNullException">If the argument to the <see cref="CultureInfoAttribute"/> is <see langword="null"/>.</exception>
+		/// <exception cref="CultureNotFoundException">If the argument to the <see cref="CultureInfoAttribute"/> does not specify a supported culture.</exception>
+		public static CsvConfiguration FromType(Type type)
+		{
+			var cultureInfoAttribute = (CultureInfoAttribute?)Attribute.GetCustomAttribute(type, typeof(CultureInfoAttribute));
+
+			if (cultureInfoAttribute is null)
+			{
+				throw new ConfigurationException($"{type} is not configured with {nameof(CultureInfoAttribute)} at the type level");
+			}
+
+			var config = new CsvConfiguration(cultureInfoAttribute.CultureInfo);
+			config.ApplyAttributes(type);
+			return config;
+		}
+
+		/// <summary>
+		/// Creates a <see cref="CsvConfiguration"/> instance configured using <paramref name="cultureInfo"/>
+		/// and CsvHelper attributes applied to <paramref name="type"/> at the type-level.
+		/// This method ignores any <see cref="CultureInfoAttribute"/> applied to <paramref name="type"/>.
+		/// </summary>
+		/// <param name="type"><inheritdoc cref="FromType{T}()" path="/typeparam"/></param>
+		/// <param name="cultureInfo"><inheritdoc cref="FromType{T}(CultureInfo)"/></param>
+		/// <returns>A new <see cref="CsvConfiguration"/> instance configured with <paramref name="cultureInfo"/> and attributes applied to <paramref name="type"/></returns>
+		/// <remarks><inheritdoc cref="FromType{T}()"/></remarks>
+		public static CsvConfiguration FromType(Type type, CultureInfo cultureInfo)
+		{
+			var config = new CsvConfiguration(cultureInfo);
+			config.ApplyAttributes(type);
+			return config;
+		}
 	}
 }


Test patch:
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs
index e5fb1ebf9..f417c19ba 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs
@@ -14,12 +14,20 @@ public class AllowCommentsTests
 		[Fact]
 		public void AllowCommentsTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(AllowCommentsTestClass));
-			Assert.True(config.AllowComments);
+			Assert.True(CsvConfiguration.FromType<AllowCommentsTrueTestClass>(CultureInfo.InvariantCulture).AllowComments);
+			Assert.False(CsvConfiguration.FromType<AllowCommentsFalseTestClass>(CultureInfo.InvariantCulture).AllowComments);
 		}
 
-		[AllowComments(true)]
-		private class AllowCommentsTestClass
+		[AllowComments]
+		private class AllowCommentsTrueTestClass
+		{
+			public int Id { get; set; }
+
+			public string Name { get; set; }
+		}
+
+		[AllowComments(false)]
+		private class AllowCommentsFalseTestClass
 		{
 			public int Id { get; set; }
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs
index dd3549819..b6825e2e3 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs
@@ -15,7 +15,7 @@ public class BufferSizeTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(2, config.BufferSize);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs
index bfc1c5232..1badda9d5 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs
@@ -10,11 +10,14 @@ public class CacheFieldsTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.True(config.CacheFields);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).CacheFields);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).CacheFields);
 		}
 
-		[CacheFields(true)]
-		private class Foo { }
+		[CacheFields]
+		private class FooTrue { }
+
+		[CacheFields(false)]
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs
index 64baf141d..0924bcd2e 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs
@@ -16,7 +16,7 @@ public class CommentTests
         [Fact]
         public void CommentTest()
         {
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(CommentTestClass));
+			var config = CsvConfiguration.FromType<CommentTestClass>(CultureInfo.InvariantCulture);
             Assert.Equal('x', config.Comment);
         }
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs b/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs
index c4847cdbe..27cd41c23 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs
@@ -10,11 +10,14 @@ public class CountBytesTest
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.True(config.CountBytes);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).CountBytes);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).CountBytes);
 		}
 
-		[CountBytes(true)]
-		private class Foo { }
+		[CountBytes]
+		private class FooTrue { }
+
+		[CountBytes(false)]
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs
index 331512668..2fc7ddeca 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs
@@ -16,7 +16,7 @@ public class DelimiterTests
 		[Fact]
 		public void DelimiterReaderTest()
 		{
-			var configuration = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(DelimiterTestClass));
+			var configuration = CsvConfiguration.FromType<DelimiterTestClass>(CultureInfo.InvariantCulture);
 
 			Assert.Equal("§", configuration.Delimiter);
 		}
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs
index 4fad81642..6da63ba84 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs
@@ -10,11 +10,14 @@ public class DetectColumnCountChangesTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.True(config.DetectColumnCountChanges);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).DetectColumnCountChanges);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).DetectColumnCountChanges);
 		}
 
-		[DetectColumnCountChanges(true)]
-		private class Foo { }
+		[DetectColumnCountChanges]
+		private class FooTrue { }
+
+		[DetectColumnCountChanges(false)]
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs
index 1ccc0fb35..3fd9ef0f7 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs
@@ -10,11 +10,14 @@ public class DetectDelimiterTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.True(config.DetectDelimiter);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).DetectDelimiter);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).DetectDelimiter);
 		}
 
-		[DetectDelimiter(true)]
-		private class Foo { }
+		[DetectDelimiter]
+		private class FooTrue { }
+
+		[DetectDelimiter(false)]
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs
index a1600015e..f99822822 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs
@@ -15,7 +15,7 @@ public class DetectDelimiterValuesTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(new[] { "a", "b" }, config.DetectDelimiterValues);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs
index 557775b55..ee4a7c19a 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs
@@ -5,8 +5,6 @@
 using CsvHelper.Configuration;
 using CsvHelper.Configuration.Attributes;
 using System.Globalization;
-using System.IO;
-using System.Linq;
 using System.Text;
 using Xunit;
 
@@ -17,13 +15,20 @@ public class EncodingTests
 		[Fact]
 		public void EncodingTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(EncodingTestClass));
-
-			Assert.Equal(Encoding.ASCII, config.Encoding);
+			Assert.Equal(Encoding.ASCII, CsvConfiguration.FromType<EncodingNameTestClass>(CultureInfo.InvariantCulture).Encoding);
+			Assert.Equal(Encoding.ASCII, CsvConfiguration.FromType<EncodingCodepageTestClass>(CultureInfo.InvariantCulture).Encoding);
 		}
 
 		[Encoding("ASCII")]
-		private class EncodingTestClass
+		private class EncodingNameTestClass
+		{
+			public int Id { get; set; }
+
+			public string Name { get; set; }
+		}
+
+		[Encoding(20127)]
+		private class EncodingCodepageTestClass
 		{
 			public int Id { get; set; }
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs
index b3c3e7f5b..87c846a8d 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs
@@ -16,7 +16,7 @@ public class EscapeTests
 		[Fact]
 		public void EscapeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(EscapeTestClass));
+			var config = CsvConfiguration.FromType<EscapeTestClass>(CultureInfo.InvariantCulture);
 
 			Assert.Equal('x', config.Escape);
 		}
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs
index ce3688e33..244ac1759 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs
@@ -1,11 +1,6 @@
 ﻿using CsvHelper.Configuration;
 using CsvHelper.Configuration.Attributes;
-using System;
-using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using Xunit;
 
 namespace CsvHelper.Tests.Mappings.Attribute
@@ -15,11 +10,14 @@ public class ExceptionMessagesContainRawDataTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.False(config.ExceptionMessagesContainRawData);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).ExceptionMessagesContainRawData);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).ExceptionMessagesContainRawData);
 		}
 
+		[ExceptionMessagesContainRawData]
+		private class FooTrue { }
+
 		[ExceptionMessagesContainRawData(false)]
-		private class Foo { }
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs
index 9fae8725b..a534860c5 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs
@@ -14,13 +14,20 @@ public class HasHeaderRecordTests
 		[Fact]
 		public void HasHeaderRecordTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(HasHeaderRecordTestClass));
+			Assert.True(CsvConfiguration.FromType<HasHeaderRecordTrueTestClass>(CultureInfo.InvariantCulture).HasHeaderRecord);
+			Assert.False(CsvConfiguration.FromType<HasHeaderRecordFalseTestClass>(CultureInfo.InvariantCulture).HasHeaderRecord);
+		}
 
-			Assert.False(config.HasHeaderRecord);
+		[HasHeaderRecord]
+		private class HasHeaderRecordTrueTestClass
+		{
+			public int Id { get; set; }
+
+			public string Name { get; set; }
 		}
 
 		[HasHeaderRecord(false)]
-		private class HasHeaderRecordTestClass
+		private class HasHeaderRecordFalseTestClass
 		{
 			public int Id { get; set; }
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs
index b2ec8e07f..6b7feee9f 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs
@@ -2,10 +2,9 @@
 // This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
 // See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
 // http://csvhelper.com
+using CsvHelper.Configuration;
 using CsvHelper.Configuration.Attributes;
 using System.Globalization;
-using System.IO;
-using System.Linq;
 using Xunit;
 
 namespace CsvHelper.Tests.AttributeMapping
@@ -15,18 +14,20 @@ public class IgnoreBlankLinesTests
 		[Fact]
 		public void IgnoreBlankLinesTest()
 		{
-			using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
-			using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
-			{
-				var records = csv.GetRecords<IgnoreBlankLinesTestClass>().ToList();
-				var actual = csv.Configuration.IgnoreBlankLines;
+			Assert.True(CsvConfiguration.FromType<IgnoreBlankLinesTrueTestClass>(CultureInfo.InvariantCulture).IgnoreBlankLines);
+			Assert.False(CsvConfiguration.FromType<IgnoreBlankLinesFalseTestClass>(CultureInfo.InvariantCulture).IgnoreBlankLines);
+		}
 
-				Assert.True(actual);
-			}
+		[IgnoreBlankLines]
+		private class IgnoreBlankLinesTrueTestClass
+		{
+			public int Id { get; set; }
+
+			public string Name { get; set; }
 		}
 
-		[IgnoreBlankLines(true)]
-		private class IgnoreBlankLinesTestClass
+		[IgnoreBlankLines(false)]
+		private class IgnoreBlankLinesFalseTestClass
 		{
 			public int Id { get; set; }
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs
index f2839b6a0..daba9d682 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs
@@ -1,11 +1,6 @@
 ﻿using CsvHelper.Configuration;
 using CsvHelper.Configuration.Attributes;
-using System;
-using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using Xunit;
 
 namespace CsvHelper.Tests.Mappings.Attribute
@@ -15,11 +10,14 @@ public class IgnoreReferencesTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.True(config.IgnoreReferences);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).IgnoreReferences);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).IgnoreReferences);
 		}
 
-		[IgnoreReferences(true)]
-		private class Foo { }
+		[IgnoreReferences]
+		private class FooTrue { }
+
+		[IgnoreReferences(false)]
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs
index 2b219dcb6..fc11e6fba 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs
@@ -12,14 +12,22 @@ namespace CsvHelper.Tests.AttributeMapping
 	public class IncludePrivateMembersTests
 	{
 		[Fact]
-		public void TrimOptionsTest()
+		public void IncludePrivateMembersTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(IncludePrivateMembersTestClass));
-			Assert.True(config.IncludePrivateMembers);
+			Assert.True(CsvConfiguration.FromType<IncludePrivateMembersTrueTestClass>(CultureInfo.InvariantCulture).IncludePrivateMembers);
+			Assert.False(CsvConfiguration.FromType<IncludePrivateMembersFalseTestClass>(CultureInfo.InvariantCulture).IncludePrivateMembers);
 		}
 
-		[IncludePrivateMembers(true)]
-		private class IncludePrivateMembersTestClass
+		[IncludePrivateMembers]
+		private class IncludePrivateMembersTrueTestClass
+		{
+			public int Id { get; set; }
+
+			public string Name { get; set; }
+		}
+
+		[IncludePrivateMembers(false)]
+		private class IncludePrivateMembersFalseTestClass
 		{
 			public int Id { get; set; }
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs
index b4fc82cd3..211582343 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs
@@ -15,7 +15,7 @@ public class InjectionCharactersTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(new[] { 'a', 'b' }, config.InjectionCharacters);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs
index e118ea23e..697ddbdae 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs
@@ -15,7 +15,7 @@ public class InjectionEscapeCharacterTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal('a', config.InjectionEscapeCharacter);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs
index 7a0300355..94cc7d6b8 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs
@@ -15,7 +15,7 @@ public class InjectionOptionsTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(InjectionOptions.Escape, config.InjectionOptions);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs
index b9397801e..0e5707553 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs
@@ -1,11 +1,6 @@
 ﻿using CsvHelper.Configuration;
 using CsvHelper.Configuration.Attributes;
-using System;
-using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using Xunit;
 
 namespace CsvHelper.Tests.Mappings.Attribute
@@ -15,11 +10,14 @@ public class LineBreakInQuotedFieldIsBadDataTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.True(config.LineBreakInQuotedFieldIsBadData);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).LineBreakInQuotedFieldIsBadData);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).LineBreakInQuotedFieldIsBadData);
 		}
 
-		[LineBreakInQuotedFieldIsBadData(true)]
-		private class Foo { }
+		[LineBreakInQuotedFieldIsBadData]
+		private class FooTrue { }
+
+		[LineBreakInQuotedFieldIsBadData(false)]
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs
index b0a923196..3d662182d 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs
@@ -10,7 +10,7 @@ public class MaxFieldSizeTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(2, config.MaxFieldSize);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs
index be21b325b..0fbc373ee 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs
@@ -10,7 +10,7 @@ public class MemberTypesTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(MemberTypes.Fields, config.MemberTypes);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs
index ca3586309..a4ca5cf98 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs
@@ -10,7 +10,7 @@ public class ModeTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(CsvMode.Escape, config.Mode);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs
index 5d9ba80d6..12ac245d2 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs
@@ -10,7 +10,7 @@ public class NewLineTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal("a", config.NewLine);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs
index 63ea4330a..7d1f3bbfb 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs
@@ -10,7 +10,7 @@ public class ProcessFieldBufferSizeTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(2, config.ProcessFieldBufferSize);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs
index 3b6fb4175..a72ace8da 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs
@@ -14,7 +14,7 @@ public class QuoteTests
 		[Fact]
 		public void QuoteTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(QuoteTestClass));
+			var config = CsvConfiguration.FromType<QuoteTestClass>(CultureInfo.InvariantCulture);
 			Assert.Equal('x', config.Quote);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs
index 6e7595ffc..5fbd73caf 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs
@@ -16,7 +16,7 @@ public class TrimOptionsTests
 		[Fact]
 		public void TrimOptionsTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(TrimOptionsTestClass));
+			var config = CsvConfiguration.FromType<TrimOptionsTestClass>(CultureInfo.InvariantCulture);
 			Assert.Equal(TrimOptions.InsideQuotes, config.TrimOptions);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs
index d5608721d..412c6b623 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs
@@ -10,11 +10,14 @@ public class UseNewObjectForNullReferenceMembersTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
-			Assert.False(config.UseNewObjectForNullReferenceMembers);
+			Assert.True(CsvConfiguration.FromType<FooTrue>(CultureInfo.InvariantCulture).UseNewObjectForNullReferenceMembers);
+			Assert.False(CsvConfiguration.FromType<FooFalse>(CultureInfo.InvariantCulture).UseNewObjectForNullReferenceMembers);
 		}
 
+		[UseNewObjectForNullReferenceMembers]
+		private class FooTrue { }
+
 		[UseNewObjectForNullReferenceMembers(false)]
-		private class Foo { }
+		private class FooFalse { }
 	}
 }
diff --git a/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs b/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs
index 3abb02721..e1dee3efa 100644
--- a/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs
@@ -10,7 +10,7 @@ public class WhiteSpaceCharsTests
 		[Fact]
 		public void ConstructorAttributeTest()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+			var config = CsvConfiguration.FromType<Foo>(CultureInfo.InvariantCulture);
 			Assert.Equal(new[] { 'a', 'b' }, config.WhiteSpaceChars);
 		}
 
diff --git a/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs b/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs
index cb9d08dbb..b051e2efd 100644
--- a/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs
+++ b/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs
@@ -6,43 +6,54 @@
 using CsvHelper.Configuration.Attributes;
 using CsvHelper.Tests.Mocks;
 using Xunit;
-using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Text;
-using System.Threading.Tasks;
-using System.Threading;
+using System;
 
 namespace CsvHelper.Tests.Mappings.ConstructorParameter
 {
 	
     public class CultureInfoAttributeTests
     {
-		private const decimal AMOUNT = 123_456.789M;
-		private const string CULTURE = "fr-FR";
-		private readonly string amount = AMOUNT.ToString(new CultureInfo(CULTURE));
-
 		[Fact]
 		public void AutoMap_WithCultureInfoAttributes_ConfiguresParameterMaps()
-		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+		{			
+			var config = CsvConfiguration.FromType<Foo>();
 			var context = new CsvContext(config);
 			var map = context.AutoMap<Foo>();
 
-			Assert.Equal(2, map.ParameterMaps.Count);
+			Assert.Equal(3, map.ParameterMaps.Count);
 			Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.CultureInfo);
-			Assert.Equal(new CultureInfo(CULTURE), map.ParameterMaps[1].Data.TypeConverterOptions.CultureInfo);
+			Assert.Equal(new CultureInfo("fr-FR"), map.ParameterMaps[1].Data.TypeConverterOptions.CultureInfo);
+			Assert.Null(map.ParameterMaps[2].Data.TypeConverterOptions.CultureInfo);
+			Assert.Equal(CultureInfo.InvariantCulture, context.Configuration.CultureInfo);
+		}
+
+		[Fact]
+		public void AutoMap_WithCultureInfoAttributes_ConfiguresMemberMaps()
+		{
+			var config = CsvConfiguration.FromType<Foo2>();
+			var context = new CsvContext(config);
+			var map = context.AutoMap<Foo2>();
+
+			Assert.Equal(4, map.MemberMaps.Count);
+			Assert.Null(map.MemberMaps[0].Data.TypeConverterOptions.CultureInfo);
+			Assert.Equal(new CultureInfo("fr-FR"), map.MemberMaps[1].Data.TypeConverterOptions.CultureInfo);
+			Assert.Equal(CultureInfo.InvariantCulture, map.MemberMaps[2].Data.TypeConverterOptions.CultureInfo);
+			Assert.Equal(new CultureInfo("ps-AF"), map.MemberMaps[3].Data.TypeConverterOptions.CultureInfo);
+			Assert.Equal(new CultureInfo("en-GB"), context.Configuration.CultureInfo);
 		}
 
 		[Fact]
-		public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
+		public void GetRecords_WithCultureInfoAttributes_CreatesRecords()
 		{
 			var parser = new ParserMock
 			{
-				{ "id", "amount" },
-				{ "1", amount },
+				{ "id", "amount1", "amount2" },
+				{ "1", "1,234", "1,234" },
 			};
 			using (var csv = new CsvReader(parser))
 			{
@@ -50,70 +61,164 @@ public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
 
 				Assert.Single(records);
 				Assert.Equal(1, records[0].Id);
-				Assert.Equal(AMOUNT, records[0].Amount);
+				Assert.Equal(1.234m, records[0].Amount1);
+				Assert.Equal(1234, records[0].Amount2);
 			}
 		}
 
 		[Fact]
-		public void GetRecords_WithCultureInfoAttributes_NoHeader_CreatesRecords()
+		public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
 		{
-			var config = new CsvConfiguration(CultureInfo.InvariantCulture)
-			{
-				HasHeaderRecord = false,
-			};
-			var parser = new ParserMock(config)
+			var records = new List<Foo>
 			{
-				{ "1", amount },
+				new Foo(1, 1.234m, 1.234m),
 			};
-			using (var csv = new CsvReader(parser))
+
+			using (var writer = new StringWriter())
+			using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
 			{
-				var records = csv.GetRecords<Foo>().ToList();
+				csv.WriteRecords(records);
 
-				Assert.Single(records);
-				Assert.Equal(1, records[0].Id);
-				Assert.Equal(AMOUNT, records[0].Amount);
-			}
+				var expected = new StringBuilder();
+				expected.Append("Id,Amount1,Amount2\r\n");
+				expected.Append("1,1.234,1.234\r\n");
+
+				Assert.Equal(expected.ToString(), writer.ToString());
+			}
 		}
 
 		[Fact]
-		public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
+		public void WriteRecords_WithCultureInfoAttributes_DoesUseMemberMaps()
 		{
-			var records = new List<Foo>
+			var records = new List<Foo2>
 			{
-				new Foo(1, AMOUNT),
+				new Foo2
+				{
+					Id = 1,
+					Amount1 = 1.234m,
+					Amount2 = 1.234m,
+					Amount3 = 1.234m,
+				},
 			};
 
-			var prevCulture = Thread.CurrentThread.CurrentCulture;
-			try {
-				Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
-				using (var writer = new StringWriter())
-				using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
-				{
-					csv.WriteRecords(records);
+			using (var writer = new StringWriter())
+			using (var csv = new CsvWriter(writer, CultureInfo.GetCultureInfo("en-GB")))
+			{
+				csv.WriteRecords(records);
 
-					var expected = new StringBuilder();
-					expected.Append("Id,Amount\r\n");
-					expected.Append($"1,{AMOUNT}\r\n");
+				var expected = new StringBuilder();
+				expected.Append("Id,Amount1,Amount2,Amount3\r\n");
+				expected.Append("1,\"1,234\",1.234,1٫234\r\n");
 
-					Assert.Equal(expected.ToString(), writer.ToString());
-				}
-			} finally {
-				Thread.CurrentThread.CurrentCulture = prevCulture;
-			}
+				Assert.Equal(expected.ToString(), writer.ToString());
+			}
 		}
-
+
+		[CultureInfo(nameof(CultureInfo.InvariantCulture))]
 		private class Foo
 		{
 			public int Id { get; private set; }
 
-			public decimal Amount { get; private set; }
+			public decimal Amount1 { get; private set; }
+
+			public decimal Amount2 { get; private set; }
 
-			public Foo(int id, [CultureInfo(CULTURE)] decimal amount)
+			public Foo(int id, [CultureInfo("fr-FR")] decimal amount1, decimal amount2)
 			{
 				Id = id;
-				Amount = amount;
+				Amount1 = amount1;
+				Amount2 = amount2;
 			}
 		}
+
+		[CultureInfo("en-GB")]
+		private class Foo2
+		{
+			public int Id { get; set; }
+
+			[CultureInfo("fr-FR")]
+			public decimal Amount1 { get; set; }
+
+			[CultureInfo(nameof(CultureInfo.InvariantCulture))]
+			public decimal Amount2 { get; set; }
+
+			[CultureInfo("ps-AF")] // Pashto (Afghanistan) uses U+066B ARABIC DECIMAL SEPARATOR (٫ instead of ,)
+			public decimal Amount3 { get; set; }
+		}
+
+		[Fact]
+		public void CsvConfiguration_FromTypeWithParameter_IgnoresAttribute()
+		{
+			// First just validate we have an attribute to ignore
+			Assert.Equal(new CultureInfo("en-GB"), ((CultureInfoAttribute)System.Attribute.GetCustomAttribute(typeof(Foo2), typeof(CultureInfoAttribute))).CultureInfo);
+
+			Assert.Equal(new CultureInfo("es-ES"), CsvConfiguration.FromType<Foo2>(CultureInfo.GetCultureInfo("es-ES")).CultureInfo);
+		}
+
+		[Fact]
+		public void CsvConfiguration_FromType_NoAttribute_ThrowsConfigurationException()
+		{
+			Assert.Throws<ConfigurationException>(CsvConfiguration.FromType<NoAttribute>);
+		}
+
+		[Fact]
+		public void CsvConfiguration_FromType_NullAttribute_ThrowsArgumentNullException()
+		{
+			Assert.Throws<ArgumentNullException>(CsvConfiguration.FromType<NullAttribute>);
+		}
+
+		[Fact]
+		public void CsvConfiguration_FromType_InvalidAttribute_ThrowsCultureNotFoundException()
+		{
+			Assert.Throws<CultureNotFoundException>(CsvConfiguration.FromType<InvalidAttribute>);
+		}
+
+		[Fact]
+		public void CsvConfiguration_FromType_DerivedNoAttribute_TakesBaseClassValue()
+		{
+			Assert.Equal(new CultureInfo("en-GB"), CsvConfiguration.FromType<Foo2DerivedNoAttribute>().CultureInfo);
+		}
+
+		[Fact]
+		public void CsvConfiguration_FromType_DerivedWithAttribute_TakesDerviedClassValue()
+		{
+			Assert.Equal(CultureInfo.CurrentCulture, CsvConfiguration.FromType<Foo2DerivedWithAttribute>().CultureInfo);
+		}
 
+		private class NoAttribute
+		{
+			[CultureInfo("fr-FR")]
+			public int Id { get; set; }
+
+			[CultureInfo("fr-FR")]
+			public decimal Amount { get; set; }
+		}
+
+		[CultureInfo(null)]
+		private class NullAttribute
+		{
+			[CultureInfo("fr-FR")]
+			public int Id { get; set; }
+
+			[CultureInfo("fr-FR")]
+			public decimal Amount { get; set; }
+		}
+
+		[CultureInfo("invalid")]
+		private class InvalidAttribute
+		{
+			[CultureInfo("fr-FR")]
+			public int Id { get; set; }
+
+			[CultureInfo("fr-FR")]
+			public decimal Amount { get; set; }
+		}
+
+		private class Foo2DerivedNoAttribute : Foo2
+		{ }
+
+		[CultureInfo(nameof(CultureInfo.CurrentCulture))]
+		private class Foo2DerivedWithAttribute : Foo2
+		{ }
 	}
 }