Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
Dapper
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
Dapper
Commits
9846b9af
Commit
9846b9af
authored
Oct 28, 2014
by
kevin-montrose
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
whack at an explicit constructor switch
parent
8e33a56d
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
131 additions
and
10 deletions
+131
-10
SqlMapper.cs
Dapper NET40/SqlMapper.cs
+94
-10
Tests.cs
Tests/Tests.cs
+37
-0
No files found.
Dapper NET40/SqlMapper.cs
View file @
9846b9af
...
@@ -389,6 +389,15 @@ public interface ITypeMap
...
@@ -389,6 +389,15 @@ public interface ITypeMap
/// <returns>Matching constructor or default one</returns>
/// <returns>Matching constructor or default one</returns>
ConstructorInfo
FindConstructor
(
string
[]
names
,
Type
[]
types
);
ConstructorInfo
FindConstructor
(
string
[]
names
,
Type
[]
types
);
/// <summary>
/// Returns a constructor which should *always* be used.
///
/// Parameters will be default values, nulls for reference types and zero'd for value types.
///
/// Use this class to force object creation away from parameterless constructors you dn't control.
/// </summary>
ConstructorInfo
FindExplicitConstructor
();
/// <summary>
/// <summary>
/// Gets mapping for constructor parameter
/// Gets mapping for constructor parameter
/// </summary>
/// </summary>
...
@@ -3557,6 +3566,44 @@ public static void SetTypeMap(Type type, ITypeMap map)
...
@@ -3557,6 +3566,44 @@ public static void SetTypeMap(Type type, ITypeMap map)
types
[
i
-
startBound
]
=
reader
.
GetFieldType
(
i
);
types
[
i
-
startBound
]
=
reader
.
GetFieldType
(
i
);
}
}
var
explicitConstr
=
typeMap
.
FindExplicitConstructor
();
if
(
explicitConstr
!=
null
)
{
var
structLocals
=
new
Dictionary
<
Type
,
LocalBuilder
>();
var
consPs
=
explicitConstr
.
GetParameters
();
foreach
(
var
p
in
consPs
)
{
if
(!
p
.
ParameterType
.
IsValueType
)
{
il
.
Emit
(
OpCodes
.
Ldnull
);
}
else
{
LocalBuilder
loc
;
if
(!
structLocals
.
TryGetValue
(
p
.
ParameterType
,
out
loc
))
{
structLocals
[
p
.
ParameterType
]
=
loc
=
il
.
DeclareLocal
(
p
.
ParameterType
);
}
il
.
Emit
(
OpCodes
.
Ldloca
,
(
short
)
loc
.
LocalIndex
);
il
.
Emit
(
OpCodes
.
Initobj
,
p
.
ParameterType
);
il
.
Emit
(
OpCodes
.
Ldloca
,
(
short
)
loc
.
LocalIndex
);
il
.
Emit
(
OpCodes
.
Ldobj
,
p
.
ParameterType
);
}
}
il
.
Emit
(
OpCodes
.
Newobj
,
explicitConstr
);
il
.
Emit
(
OpCodes
.
Stloc_1
);
supportInitialize
=
typeof
(
ISupportInitialize
).
IsAssignableFrom
(
type
);
if
(
supportInitialize
)
{
il
.
Emit
(
OpCodes
.
Ldloc_1
);
il
.
EmitCall
(
OpCodes
.
Callvirt
,
typeof
(
ISupportInitialize
).
GetMethod
(
"BeginInit"
),
null
);
}
}
else
{
var
ctor
=
typeMap
.
FindConstructor
(
names
,
types
);
var
ctor
=
typeMap
.
FindConstructor
(
names
,
types
);
if
(
ctor
==
null
)
if
(
ctor
==
null
)
{
{
...
@@ -3569,15 +3616,18 @@ public static void SetTypeMap(Type type, ITypeMap map)
...
@@ -3569,15 +3616,18 @@ public static void SetTypeMap(Type type, ITypeMap map)
il
.
Emit
(
OpCodes
.
Newobj
,
ctor
);
il
.
Emit
(
OpCodes
.
Newobj
,
ctor
);
il
.
Emit
(
OpCodes
.
Stloc_1
);
il
.
Emit
(
OpCodes
.
Stloc_1
);
supportInitialize
=
typeof
(
ISupportInitialize
).
IsAssignableFrom
(
type
);
supportInitialize
=
typeof
(
ISupportInitialize
).
IsAssignableFrom
(
type
);
if
(
supportInitialize
)
if
(
supportInitialize
)
{
{
il
.
Emit
(
OpCodes
.
Ldloc_1
);
il
.
Emit
(
OpCodes
.
Ldloc_1
);
il
.
EmitCall
(
OpCodes
.
Callvirt
,
typeof
(
ISupportInitialize
).
GetMethod
(
"BeginInit"
),
null
);
il
.
EmitCall
(
OpCodes
.
Callvirt
,
typeof
(
ISupportInitialize
).
GetMethod
(
"BeginInit"
),
null
);
}
}
}
}
else
else
{
specializedConstructor
=
ctor
;
specializedConstructor
=
ctor
;
}
}
}
}
il
.
BeginExceptionBlock
();
il
.
BeginExceptionBlock
();
if
(
type
.
IsValueType
)
if
(
type
.
IsValueType
)
...
@@ -5216,6 +5266,22 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
...
@@ -5216,6 +5266,22 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
return
null
;
return
null
;
}
}
/// <summary>
/// Returns the constructor, if any, that has the ExplicitConstructorAttribute on it.
/// </summary>
public
ConstructorInfo
FindExplicitConstructor
()
{
var
constructors
=
_type
.
GetConstructors
(
BindingFlags
.
Instance
|
BindingFlags
.
Public
|
BindingFlags
.
NonPublic
);
var
withAttr
=
constructors
.
Where
(
c
=>
c
.
GetCustomAttributes
(
typeof
(
ExplicitConstructorAttribute
),
true
).
Length
>
0
).
ToList
();
if
(
withAttr
.
Count
==
1
)
{
return
withAttr
[
0
];
}
return
null
;
}
/// <summary>
/// <summary>
/// Gets mapping for constructor parameter
/// Gets mapping for constructor parameter
/// </summary>
/// </summary>
...
@@ -5306,6 +5372,15 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
...
@@ -5306,6 +5372,15 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
return
_type
.
GetConstructor
(
new
Type
[
0
]);
return
_type
.
GetConstructor
(
new
Type
[
0
]);
}
}
/// <summary>
/// Always returns null
/// </summary>
/// <returns></returns>
public
ConstructorInfo
FindExplicitConstructor
()
{
return
null
;
}
/// <summary>
/// <summary>
/// Not impelmeneted as far as default constructor used for all cases
/// Not impelmeneted as far as default constructor used for all cases
/// </summary>
/// </summary>
...
@@ -5544,6 +5619,15 @@ public interface IWrappedDataReader : IDataReader
...
@@ -5544,6 +5619,15 @@ public interface IWrappedDataReader : IDataReader
IDbCommand
Command
{
get
;
}
IDbCommand
Command
{
get
;
}
}
}
/// <summary>
/// Tell Dapper to use an explicit constructor, passing nulls or 0s for all parameters
/// </summary>
[
AttributeUsage
(
AttributeTargets
.
Constructor
,
AllowMultiple
=
false
)]
public
sealed
class
ExplicitConstructorAttribute
:
Attribute
{
}
// Define DAPPER_MAKE_PRIVATE if you reference Dapper by source
// Define DAPPER_MAKE_PRIVATE if you reference Dapper by source
// and you like to make the Dapper types private (in order to avoid
// and you like to make the Dapper types private (in order to avoid
// conflicts with other projects that also reference Dapper by source)
// conflicts with other projects that also reference Dapper by source)
...
...
Tests/Tests.cs
View file @
9846b9af
...
@@ -4086,6 +4086,43 @@ public void Issue192_InParameterWorksWithSimilarNamesWithUnicode()
...
@@ -4086,6 +4086,43 @@ public void Issue192_InParameterWorksWithSimilarNamesWithUnicode()
((
int
)
rows
.
Field
).
IsEqualTo
(
2
);
((
int
)
rows
.
Field
).
IsEqualTo
(
2
);
((
int
)
rows
.
Field_1
).
IsEqualTo
(
2
);
((
int
)
rows
.
Field_1
).
IsEqualTo
(
2
);
}
}
class
_ExplicitConstructors
{
public
int
Field
{
get
;
set
;
}
public
int
Field_1
{
get
;
set
;
}
private
bool
WentThroughProperConstructor
;
public
_ExplicitConstructors
()
{
}
[
ExplicitConstructor
]
public
_ExplicitConstructors
(
string
foo
,
int
bar
)
{
WentThroughProperConstructor
=
true
;
}
public
bool
GetWentThroughProperConstructor
()
{
return
WentThroughProperConstructor
;
}
}
public
void
ExplicitConstructors
()
{
var
rows
=
connection
.
Query
<
_ExplicitConstructors
>(
@"
declare @ExplicitConstructors table (
Field INT NOT NULL PRIMARY KEY IDENTITY(1,1),
Field_1 INT NOT NULL);
insert @ExplicitConstructors(Field_1) values (1);
SELECT * FROM @ExplicitConstructors"
).
ToList
();
rows
.
Count
.
IsEqualTo
(
1
);
rows
[
0
].
Field
.
IsEqualTo
(
1
);
rows
[
0
].
Field_1
.
IsEqualTo
(
1
);
rows
[
0
].
GetWentThroughProperConstructor
().
IsTrue
();
}
#if POSTGRESQL
#if POSTGRESQL
class
Cat
class
Cat
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment