Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CAP
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
CAP
Commits
297cecfa
Commit
297cecfa
authored
Jul 26, 2017
by
yangxiaodong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix issue #17.
parent
31b0c8c7
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
387 additions
and
129 deletions
+387
-129
IModelBinder.cs
src/DotNetCore.CAP/Abstractions/ModelBinding/IModelBinder.cs
+1
-10
ModelBindingContext.cs
...Core.CAP/Abstractions/ModelBinding/ModelBindingContext.cs
+0
-55
ModelBindingResult.cs
...tCore.CAP/Abstractions/ModelBinding/ModelBindingResult.cs
+56
-0
CAP.ServiceCollectionExtensions.cs
src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs
+1
-1
ConsumerInvokerFactory.cs
src/DotNetCore.CAP/Internal/ConsumerInvokerFactory.cs
+4
-4
HashCodeCombiner.cs
src/DotNetCore.CAP/Internal/HashCodeCombiner.cs
+81
-0
IConsumerInvoker.Default.cs
src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs
+14
-12
IModelBinder.ComplexType.cs
src/DotNetCore.CAP/Internal/IModelBinder.ComplexType.cs
+33
-0
IModelBinder.Default.cs
src/DotNetCore.CAP/Internal/IModelBinder.Default.cs
+0
-47
IModelBinder.SimpleType.cs
src/DotNetCore.CAP/Internal/IModelBinder.SimpleType.cs
+71
-0
IModelBinderFactory.cs
src/DotNetCore.CAP/Internal/IModelBinderFactory.cs
+10
-0
ModelBinderFactory.cs
src/DotNetCore.CAP/Internal/ModelBinderFactory.cs
+116
-0
No files found.
src/DotNetCore.CAP/Abstractions/ModelBinding/IModelBinder.cs
View file @
297cecfa
...
@@ -7,15 +7,6 @@ namespace DotNetCore.CAP.Abstractions.ModelBinding
...
@@ -7,15 +7,6 @@ namespace DotNetCore.CAP.Abstractions.ModelBinding
/// </summary>
/// </summary>
public
interface
IModelBinder
public
interface
IModelBinder
{
{
/// <summary>
Task
<
ModelBindingResult
>
BindModelAsync
(
string
content
);
/// Attempts to bind a model.
/// </summary>
/// <param name="bindingContext">The <see cref="ModelBindingContext"/>.</param>
/// <returns>
/// <para>
/// A <see cref="Task"/> which will complete when the model binding process completes.
/// </para>
/// </returns>
Task
BindModelAsync
(
ModelBindingContext
bindingContext
);
}
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Abstractions/ModelBinding/ModelBindingContext.cs
deleted
100644 → 0
View file @
31b0c8c7
using
System
;
using
Microsoft.Extensions.Primitives
;
namespace
DotNetCore.CAP.Abstractions.ModelBinding
{
/// <summary>
/// A context that contains operating information for model binding and validation.
/// </summary>
public
class
ModelBindingContext
{
/// <summary>
/// Gets or sets the model value for the current operation.
/// </summary>
/// <remarks>
/// The <see cref="Model"/> will typically be set for a binding operation that works
/// against a pre-existing model object to update certain properties.
/// </remarks>
public
object
Model
{
get
;
set
;
}
/// <summary>
/// Gets or sets the name of the model.
/// </summary>
public
string
ModelName
{
get
;
set
;
}
/// <summary>
/// Gets or sets the type of the model.
/// </summary>
public
Type
ModelType
{
get
;
set
;
}
/// <summary>
/// Gets or sets the values of the model.
/// </summary>
public
StringValues
Values
{
get
;
set
;
}
/// <summary>
/// <para>
/// Gets or sets a result which represents the result of the model binding process.
/// </para>
/// </summary>
public
object
Result
{
get
;
set
;
}
/// <summary>
/// Creates a new <see cref="ModelBindingContext"/> for top-level model binding operation.
/// </summary>
public
static
ModelBindingContext
CreateBindingContext
(
string
values
,
string
modelName
,
Type
modelType
)
{
return
new
ModelBindingContext
()
{
ModelName
=
modelName
,
ModelType
=
modelType
,
Values
=
values
};
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Abstractions/ModelBinding/ModelBindingResult.cs
0 → 100644
View file @
297cecfa
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
namespace
DotNetCore.CAP.Abstractions.ModelBinding
{
/// <summary>
/// Contains the result of model binding.
/// </summary>
public
struct
ModelBindingResult
{
/// <summary>
/// Creates a <see cref="ModelBindingResult"/> representing a failed model binding operation.
/// </summary>
/// <returns>A <see cref="ModelBindingResult"/> representing a failed model binding operation.</returns>
public
static
ModelBindingResult
Failed
()
{
return
new
ModelBindingResult
(
model
:
null
,
isSuccess
:
false
);
}
/// <summary>
/// Creates a <see cref="ModelBindingResult"/> representing a successful model binding operation.
/// </summary>
/// <param name="model">The model value. May be <c>null.</c></param>
/// <returns>A <see cref="ModelBindingResult"/> representing a successful model bind.</returns>
public
static
ModelBindingResult
Success
(
object
model
)
{
return
new
ModelBindingResult
(
model
,
isSuccess
:
true
);
}
private
ModelBindingResult
(
object
model
,
bool
isSuccess
)
{
Model
=
model
;
IsSuccess
=
isSuccess
;
}
/// <summary>
/// Gets the model associated with this context.
/// </summary>
public
object
Model
{
get
;
}
public
bool
IsSuccess
{
get
;
}
public
override
string
ToString
()
{
if
(
IsSuccess
)
{
return
$"Success '
{
Model
}
'"
;
}
else
{
return
$"Failed"
;
}
}
}
}
src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs
View file @
297cecfa
...
@@ -35,7 +35,7 @@ namespace Microsoft.Extensions.DependencyInjection
...
@@ -35,7 +35,7 @@ namespace Microsoft.Extensions.DependencyInjection
AddSubscribeServices
(
services
);
AddSubscribeServices
(
services
);
services
.
TryAddSingleton
<
IConsumerServiceSelector
,
DefaultConsumerServiceSelector
>();
services
.
TryAddSingleton
<
IConsumerServiceSelector
,
DefaultConsumerServiceSelector
>();
services
.
TryAddSingleton
<
IModelBinder
,
DefaultModelBinder
>();
services
.
TryAddSingleton
<
IModelBinder
Factory
,
ModelBinderFactory
>();
services
.
TryAddSingleton
<
IConsumerInvokerFactory
,
ConsumerInvokerFactory
>();
services
.
TryAddSingleton
<
IConsumerInvokerFactory
,
ConsumerInvokerFactory
>();
services
.
TryAddSingleton
<
MethodMatcherCache
>();
services
.
TryAddSingleton
<
MethodMatcherCache
>();
...
...
src/DotNetCore.CAP/Internal/ConsumerInvokerFactory.cs
View file @
297cecfa
...
@@ -10,15 +10,15 @@ namespace DotNetCore.CAP.Internal
...
@@ -10,15 +10,15 @@ namespace DotNetCore.CAP.Internal
{
{
private
readonly
ILogger
_logger
;
private
readonly
ILogger
_logger
;
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IModelBinder
_modelBinder
;
private
readonly
IModelBinder
Factory
_modelBinderFactory
;
public
ConsumerInvokerFactory
(
public
ConsumerInvokerFactory
(
ILoggerFactory
loggerFactory
,
ILoggerFactory
loggerFactory
,
IModelBinder
modelBinder
,
IModelBinder
Factory
modelBinderFactory
,
IServiceProvider
serviceProvider
)
IServiceProvider
serviceProvider
)
{
{
_logger
=
loggerFactory
.
CreateLogger
<
ConsumerInvokerFactory
>();
_logger
=
loggerFactory
.
CreateLogger
<
ConsumerInvokerFactory
>();
_modelBinder
=
modelBinder
;
_modelBinder
Factory
=
modelBinderFactory
;
_serviceProvider
=
serviceProvider
;
_serviceProvider
=
serviceProvider
;
}
}
...
@@ -26,7 +26,7 @@ namespace DotNetCore.CAP.Internal
...
@@ -26,7 +26,7 @@ namespace DotNetCore.CAP.Internal
{
{
var
context
=
new
ConsumerInvokerContext
(
consumerContext
)
var
context
=
new
ConsumerInvokerContext
(
consumerContext
)
{
{
Result
=
new
DefaultConsumerInvoker
(
_logger
,
_serviceProvider
,
_modelBinder
,
consumerContext
)
Result
=
new
DefaultConsumerInvoker
(
_logger
,
_serviceProvider
,
_modelBinder
Factory
,
consumerContext
)
};
};
return
context
.
Result
;
return
context
.
Result
;
...
...
src/DotNetCore.CAP/Internal/HashCodeCombiner.cs
0 → 100644
View file @
297cecfa
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Runtime.CompilerServices
;
namespace
DotNetCore.CAP.Internal
{
internal
struct
HashCodeCombiner
{
private
long
_combinedHash64
;
public
int
CombinedHash
{
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
get
{
return
_combinedHash64
.
GetHashCode
();
}
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
private
HashCodeCombiner
(
long
seed
)
{
_combinedHash64
=
seed
;
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
void
Add
(
IEnumerable
e
)
{
if
(
e
==
null
)
{
Add
(
0
);
}
else
{
var
count
=
0
;
foreach
(
object
o
in
e
)
{
Add
(
o
);
count
++;
}
Add
(
count
);
}
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
static
implicit
operator
int
(
HashCodeCombiner
self
)
{
return
self
.
CombinedHash
;
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
void
Add
(
int
i
)
{
_combinedHash64
=
((
_combinedHash64
<<
5
)
+
_combinedHash64
)
^
i
;
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
void
Add
(
string
s
)
{
var
hashCode
=
(
s
!=
null
)
?
s
.
GetHashCode
()
:
0
;
Add
(
hashCode
);
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
void
Add
(
object
o
)
{
var
hashCode
=
(
o
!=
null
)
?
o
.
GetHashCode
()
:
0
;
Add
(
hashCode
);
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
void
Add
<
TValue
>(
TValue
value
,
IEqualityComparer
<
TValue
>
comparer
)
{
var
hashCode
=
value
!=
null
?
comparer
.
GetHashCode
(
value
)
:
0
;
Add
(
hashCode
);
}
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
public
static
HashCodeCombiner
Start
()
{
return
new
HashCodeCombiner
(
0x1505L
);
}
}
}
src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs
View file @
297cecfa
using
System
;
using
System
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Abstractions
;
using
DotNetCore.CAP.Abstractions
;
using
DotNetCore.CAP.Abstractions.ModelBinding
;
using
Microsoft.Extensions.DependencyInjection
;
using
Microsoft.Extensions.DependencyInjection
;
using
Microsoft.Extensions.Logging
;
using
Microsoft.Extensions.Logging
;
...
@@ -11,16 +10,16 @@ namespace DotNetCore.CAP.Internal
...
@@ -11,16 +10,16 @@ namespace DotNetCore.CAP.Internal
{
{
private
readonly
ILogger
_logger
;
private
readonly
ILogger
_logger
;
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IModelBinder
_modelBinder
;
private
readonly
IModelBinder
Factory
_modelBinderFactory
;
private
readonly
ConsumerContext
_consumerContext
;
private
readonly
ConsumerContext
_consumerContext
;
private
readonly
ObjectMethodExecutor
_executor
;
private
readonly
ObjectMethodExecutor
_executor
;
public
DefaultConsumerInvoker
(
ILogger
logger
,
public
DefaultConsumerInvoker
(
ILogger
logger
,
IServiceProvider
serviceProvider
,
IServiceProvider
serviceProvider
,
IModelBinder
modelBinder
,
IModelBinder
Factory
modelBinderFactory
,
ConsumerContext
consumerContext
)
ConsumerContext
consumerContext
)
{
{
_modelBinder
=
modelBinder
;
_modelBinder
Factory
=
modelBinderFactory
;
_serviceProvider
=
serviceProvider
;
_serviceProvider
=
serviceProvider
;
_logger
=
logger
??
throw
new
ArgumentNullException
(
nameof
(
logger
));
_logger
=
logger
??
throw
new
ArgumentNullException
(
nameof
(
logger
));
...
@@ -29,7 +28,7 @@ namespace DotNetCore.CAP.Internal
...
@@ -29,7 +28,7 @@ namespace DotNetCore.CAP.Internal
_consumerContext
.
ConsumerDescriptor
.
ImplTypeInfo
);
_consumerContext
.
ConsumerDescriptor
.
ImplTypeInfo
);
}
}
public
Task
InvokeAsync
()
public
async
Task
InvokeAsync
()
{
{
using
(
_logger
.
BeginScope
(
"consumer invoker begin"
))
using
(
_logger
.
BeginScope
(
"consumer invoker begin"
))
{
{
...
@@ -43,18 +42,21 @@ namespace DotNetCore.CAP.Internal
...
@@ -43,18 +42,21 @@ namespace DotNetCore.CAP.Internal
if
(
_executor
.
MethodParameters
.
Length
>
0
)
if
(
_executor
.
MethodParameters
.
Length
>
0
)
{
{
var
firstParameter
=
_executor
.
MethodParameters
[
0
];
var
firstParameter
=
_executor
.
MethodParameters
[
0
];
var
binder
=
_modelBinderFactory
.
CreateBinder
(
firstParameter
);
var
bindingContext
=
ModelBindingContext
.
CreateBindingContext
(
value
,
var
result
=
await
binder
.
BindModelAsync
(
value
);
firstParameter
.
Name
,
firstParameter
.
ParameterType
);
if
(
result
.
IsSuccess
)
{
_modelBinder
.
BindModelAsync
(
bindingContext
);
_executor
.
Execute
(
obj
,
result
.
Model
);
_executor
.
Execute
(
obj
,
bindingContext
.
Result
);
}
else
{
_logger
.
LogWarning
(
$"Parameters:
{
firstParameter
.
Name
}
bind failed!"
);
}
}
}
else
else
{
{
_executor
.
Execute
(
obj
);
_executor
.
Execute
(
obj
);
}
}
return
Task
.
CompletedTask
;
}
}
}
}
}
}
...
...
src/DotNetCore.CAP/Internal/IModelBinder.ComplexType.cs
0 → 100644
View file @
297cecfa
using
System
;
using
System.Reflection
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Abstractions.ModelBinding
;
using
DotNetCore.CAP.Infrastructure
;
namespace
DotNetCore.CAP.Internal
{
public
class
ComplexTypeModelBinder
:
IModelBinder
{
private
readonly
ParameterInfo
_parameterInfo
;
public
ComplexTypeModelBinder
(
ParameterInfo
parameterInfo
)
{
_parameterInfo
=
parameterInfo
;
}
public
Task
<
ModelBindingResult
>
BindModelAsync
(
string
content
)
{
try
{
var
type
=
_parameterInfo
.
ParameterType
;
var
value
=
Helper
.
FromJson
(
content
,
type
);
return
Task
.
FromResult
(
ModelBindingResult
.
Success
(
value
));
}
catch
(
Exception
)
{
return
Task
.
FromResult
(
ModelBindingResult
.
Failed
());
}
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Internal/IModelBinder.Default.cs
deleted
100644 → 0
View file @
31b0c8c7
using
System
;
using
System.Linq.Expressions
;
using
System.Reflection
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Abstractions.ModelBinding
;
using
DotNetCore.CAP.Infrastructure
;
namespace
DotNetCore.CAP.Internal
{
public
class
DefaultModelBinder
:
IModelBinder
{
private
Func
<
object
>
_modelCreator
;
public
Task
BindModelAsync
(
ModelBindingContext
bindingContext
)
{
if
(
bindingContext
.
Model
==
null
)
{
bindingContext
.
Model
=
CreateModel
(
bindingContext
);
}
bindingContext
.
Result
=
Helper
.
FromJson
(
bindingContext
.
Values
,
bindingContext
.
ModelType
);
return
Task
.
CompletedTask
;
}
protected
virtual
object
CreateModel
(
ModelBindingContext
bindingContext
)
{
if
(
bindingContext
==
null
)
{
throw
new
ArgumentNullException
(
nameof
(
bindingContext
));
}
if
(
_modelCreator
!=
null
)
return
_modelCreator
();
var
modelTypeInfo
=
bindingContext
.
ModelType
.
GetTypeInfo
();
if
(
modelTypeInfo
.
IsAbstract
||
modelTypeInfo
.
GetConstructor
(
Type
.
EmptyTypes
)
==
null
)
{
throw
new
InvalidOperationException
();
}
_modelCreator
=
Expression
.
Lambda
<
Func
<
object
>>(
Expression
.
New
(
bindingContext
.
ModelType
))
.
Compile
();
return
_modelCreator
();
}
}
}
\ No newline at end of file
src/DotNetCore.CAP/Internal/IModelBinder.SimpleType.cs
0 → 100644
View file @
297cecfa
using
System
;
using
System.ComponentModel
;
using
System.Globalization
;
using
System.Reflection
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Abstractions.ModelBinding
;
namespace
DotNetCore.CAP.Internal
{
public
class
SimpleTypeModelBinder
:
IModelBinder
{
private
readonly
ParameterInfo
_parameterInfo
;
private
readonly
TypeConverter
_typeConverter
;
public
SimpleTypeModelBinder
(
ParameterInfo
parameterInfo
)
{
_parameterInfo
=
parameterInfo
??
throw
new
ArgumentNullException
(
nameof
(
parameterInfo
));
_typeConverter
=
TypeDescriptor
.
GetConverter
(
parameterInfo
.
ParameterType
);
}
public
Task
<
ModelBindingResult
>
BindModelAsync
(
string
content
)
{
if
(
content
==
null
)
{
throw
new
ArgumentNullException
(
nameof
(
content
));
}
var
parameterType
=
_parameterInfo
.
ParameterType
;
object
model
;
if
(
parameterType
==
typeof
(
string
))
{
if
(
string
.
IsNullOrWhiteSpace
(
content
))
{
model
=
null
;
}
else
{
model
=
content
;
}
}
else
if
(
string
.
IsNullOrWhiteSpace
(
content
))
{
// Other than the StringConverter, converters Trim() the value then throw if the result is empty.
model
=
null
;
}
else
{
model
=
_typeConverter
.
ConvertFrom
(
context
:
null
,
culture
:
CultureInfo
.
CurrentCulture
,
value
:
content
);
}
if
(
model
==
null
&&
!
IsReferenceOrNullableType
(
parameterType
))
{
return
Task
.
FromResult
(
ModelBindingResult
.
Failed
());
}
else
{
return
Task
.
FromResult
(
ModelBindingResult
.
Success
(
model
));
}
}
private
bool
IsReferenceOrNullableType
(
Type
type
)
{
var
isNullableValueType
=
Nullable
.
GetUnderlyingType
(
type
)
!=
null
;
return
!
type
.
GetTypeInfo
().
IsValueType
||
isNullableValueType
;
}
}
}
src/DotNetCore.CAP/Internal/IModelBinderFactory.cs
0 → 100644
View file @
297cecfa
using
System.Reflection
;
using
DotNetCore.CAP.Abstractions.ModelBinding
;
namespace
DotNetCore.CAP.Internal
{
public
interface
IModelBinderFactory
{
IModelBinder
CreateBinder
(
ParameterInfo
parameter
);
}
}
src/DotNetCore.CAP/Internal/ModelBinderFactory.cs
0 → 100644
View file @
297cecfa
using
System
;
using
System.Collections.Concurrent
;
using
System.ComponentModel
;
using
System.Reflection
;
using
System.Runtime.CompilerServices
;
using
DotNetCore.CAP.Abstractions.ModelBinding
;
namespace
DotNetCore.CAP.Internal
{
/// <summary>
/// A factory for <see cref="IModelBinder"/> instances.
/// </summary>
public
class
ModelBinderFactory
:
IModelBinderFactory
{
private
readonly
ConcurrentDictionary
<
Key
,
IModelBinder
>
_cache
=
new
ConcurrentDictionary
<
Key
,
IModelBinder
>();
public
IModelBinder
CreateBinder
(
ParameterInfo
parameter
)
{
if
(
parameter
==
null
)
{
throw
new
ArgumentNullException
(
nameof
(
parameter
));
}
object
token
=
parameter
;
var
binder
=
CreateBinderCoreCached
(
parameter
,
token
);
if
(
binder
==
null
)
{
throw
new
InvalidOperationException
(
"Format Could Not Create IModelBinder"
);
}
return
binder
;
}
private
IModelBinder
CreateBinderCoreCached
(
ParameterInfo
parameterInfo
,
object
token
)
{
IModelBinder
binder
;
if
(
TryGetCachedBinder
(
parameterInfo
,
token
,
out
binder
))
{
return
binder
;
}
var
type
=
parameterInfo
.
ParameterType
;
var
isComplexType
=
!
TypeDescriptor
.
GetConverter
(
type
).
CanConvertFrom
(
typeof
(
string
));
if
(!
isComplexType
)
{
binder
=
new
SimpleTypeModelBinder
(
parameterInfo
);
}
else
{
binder
=
new
ComplexTypeModelBinder
(
parameterInfo
);
}
AddToCache
(
parameterInfo
,
token
,
binder
);
return
binder
;
}
private
void
AddToCache
(
ParameterInfo
info
,
object
cacheToken
,
IModelBinder
binder
)
{
if
(
cacheToken
==
null
)
{
return
;
}
_cache
.
TryAdd
(
new
Key
(
info
,
cacheToken
),
binder
);
}
private
bool
TryGetCachedBinder
(
ParameterInfo
info
,
object
cacheToken
,
out
IModelBinder
binder
)
{
if
(
cacheToken
==
null
)
{
binder
=
null
;
return
false
;
}
return
_cache
.
TryGetValue
(
new
Key
(
info
,
cacheToken
),
out
binder
);
}
private
struct
Key
:
IEquatable
<
Key
>
{
private
readonly
ParameterInfo
_metadata
;
private
readonly
object
_token
;
public
Key
(
ParameterInfo
metadata
,
object
token
)
{
_metadata
=
metadata
;
_token
=
token
;
}
public
bool
Equals
(
Key
other
)
{
return
_metadata
.
Equals
(
other
.
_metadata
)
&&
object
.
ReferenceEquals
(
_token
,
other
.
_token
);
}
public
override
bool
Equals
(
object
obj
)
{
var
other
=
obj
as
Key
?;
return
other
.
HasValue
&&
Equals
(
other
.
Value
);
}
public
override
int
GetHashCode
()
{
var
hash
=
new
HashCodeCombiner
();
hash
.
Add
(
_metadata
);
hash
.
Add
(
RuntimeHelpers
.
GetHashCode
(
_token
));
return
hash
;
}
public
override
string
ToString
()
{
return
$"
{
_token
}
(Property: '
{
_metadata
.
Name
}
' Type: '
{
_metadata
.
ParameterType
.
Name
}
')"
;
}
}
}
}
\ No newline at end of file
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