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
fb5dd93b
Commit
fb5dd93b
authored
Oct 30, 2014
by
Marc Gravell
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #197 from kevin-montrose/master
whack at an explicit constructor attribute
parents
8e33a56d
9846b9af
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 @
fb5dd93b
...
@@ -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 @
fb5dd93b
...
@@ -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