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
9d37dc7f
Commit
9d37dc7f
authored
Jun 28, 2019
by
Savorboard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add unit tests for ConsumerInvoker
parent
a7080292
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
261 additions
and
162 deletions
+261
-162
CAP.ServiceCollectionExtensions.cs
src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs
+1
-0
IConsumerInvoker.Default.cs
src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs
+108
-108
ConsumerInvokerTest.cs
test/DotNetCore.CAP.Test/ConsumerInvokerTest.cs
+152
-0
SubscribeFinderTest.cs
test/DotNetCore.CAP.Test/SubscribeFinderTest.cs
+0
-54
No files found.
src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs
View file @
9d37dc7f
...
@@ -22,6 +22,7 @@ namespace Microsoft.Extensions.DependencyInjection
...
@@ -22,6 +22,7 @@ namespace Microsoft.Extensions.DependencyInjection
public
static
class
ServiceCollectionExtensions
public
static
class
ServiceCollectionExtensions
{
{
internal
static
IServiceCollection
ServiceCollection
;
internal
static
IServiceCollection
ServiceCollection
;
/// <summary>
/// <summary>
/// Adds and configures the consistence services for the consistency.
/// Adds and configures the consistence services for the consistency.
/// </summary>
/// </summary>
...
...
src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs
View file @
9d37dc7f
// Copyright (c) .NET Core Community. All rights reserved.
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Licensed under the MIT License. See License.txt in the project root for license information.
using
System
;
using
System
;
using
System.Linq
;
using
System.Linq
;
using
System.Reflection
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Abstractions
;
using
DotNetCore.CAP.Abstractions
;
using
Microsoft.Extensions.DependencyInjection
;
using
Microsoft.Extensions.DependencyInjection
;
using
Microsoft.Extensions.Internal
;
using
Microsoft.Extensions.Internal
;
using
Microsoft.Extensions.Logging
;
using
Microsoft.Extensions.Logging
;
namespace
DotNetCore.CAP.Internal
namespace
DotNetCore.CAP.Internal
{
{
internal
class
DefaultConsumerInvoker
:
IConsumerInvoker
internal
class
DefaultConsumerInvoker
:
IConsumerInvoker
{
{
private
readonly
ILogger
_logger
;
private
readonly
ILogger
_logger
;
private
readonly
IMessagePacker
_messagePacker
;
private
readonly
IMessagePacker
_messagePacker
;
private
readonly
IModelBinderFactory
_modelBinderFactory
;
private
readonly
IModelBinderFactory
_modelBinderFactory
;
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IServiceProvider
_serviceProvider
;
public
DefaultConsumerInvoker
(
ILoggerFactory
loggerFactory
,
public
DefaultConsumerInvoker
(
ILoggerFactory
loggerFactory
,
IServiceProvider
serviceProvider
,
IServiceProvider
serviceProvider
,
IMessagePacker
messagePacker
,
IMessagePacker
messagePacker
,
IModelBinderFactory
modelBinderFactory
)
IModelBinderFactory
modelBinderFactory
)
{
{
_modelBinderFactory
=
modelBinderFactory
;
_modelBinderFactory
=
modelBinderFactory
;
_serviceProvider
=
serviceProvider
;
_serviceProvider
=
serviceProvider
;
_messagePacker
=
messagePacker
;
_messagePacker
=
messagePacker
;
_logger
=
loggerFactory
.
CreateLogger
<
DefaultConsumerInvoker
>();
_logger
=
loggerFactory
.
CreateLogger
<
DefaultConsumerInvoker
>();
}
}
public
async
Task
<
ConsumerExecutedResult
>
InvokeAsync
(
ConsumerContext
context
)
public
async
Task
<
ConsumerExecutedResult
>
InvokeAsync
(
ConsumerContext
context
)
{
{
_logger
.
LogDebug
(
"Executing consumer Topic: {0}"
,
context
.
ConsumerDescriptor
.
MethodInfo
.
Name
);
_logger
.
LogDebug
(
"Executing consumer Topic: {0}"
,
context
.
ConsumerDescriptor
.
MethodInfo
.
Name
);
var
executor
=
ObjectMethodExecutor
.
Create
(
var
executor
=
ObjectMethodExecutor
.
Create
(
context
.
ConsumerDescriptor
.
MethodInfo
,
context
.
ConsumerDescriptor
.
MethodInfo
,
context
.
ConsumerDescriptor
.
ImplTypeInfo
);
context
.
ConsumerDescriptor
.
ImplTypeInfo
);
using
(
var
scope
=
_serviceProvider
.
CreateScope
())
using
(
var
scope
=
_serviceProvider
.
CreateScope
())
{
{
var
provider
=
scope
.
ServiceProvider
;
var
provider
=
scope
.
ServiceProvider
;
var
serviceType
=
context
.
ConsumerDescriptor
.
ImplTypeInfo
.
AsType
();
var
srvType
=
context
.
ConsumerDescriptor
.
ServiceTypeInfo
?.
AsType
();
object
obj
=
null
;
var
implType
=
context
.
ConsumerDescriptor
.
ImplTypeInfo
.
AsType
();
if
(
context
.
ConsumerDescriptor
.
ServiceTypeInfo
!=
null
)
object
obj
=
null
;
if
(
srvType
!=
null
)
{
{
obj
=
provider
.
GetServices
(
context
.
ConsumerDescriptor
.
ServiceTypeInfo
.
AsType
())
obj
=
provider
.
GetServices
(
srvType
).
FirstOrDefault
(
o
=>
o
.
GetType
()
==
implType
);
.
FirstOrDefault
(
o
=>
o
.
GetType
()
==
serviceType
);
}
}
if
(
obj
==
null
)
if
(
obj
==
null
)
{
{
obj
=
ActivatorUtilities
.
GetServiceOrCreateInstance
(
provider
,
service
Type
);
obj
=
ActivatorUtilities
.
GetServiceOrCreateInstance
(
provider
,
impl
Type
);
}
}
var
jsonContent
=
context
.
DeliverMessage
.
Content
;
var
jsonContent
=
context
.
DeliverMessage
.
Content
;
var
message
=
_messagePacker
.
UnPack
(
jsonContent
);
var
message
=
_messagePacker
.
UnPack
(
jsonContent
);
object
resultObj
;
object
resultObj
;
if
(
executor
.
MethodParameters
.
Length
>
0
)
if
(
executor
.
MethodParameters
.
Length
>
0
)
{
{
resultObj
=
await
ExecuteWithParameterAsync
(
executor
,
obj
,
message
.
Content
);
resultObj
=
await
ExecuteWithParameterAsync
(
executor
,
obj
,
message
.
Content
);
}
}
else
else
{
{
resultObj
=
await
ExecuteAsync
(
executor
,
obj
);
resultObj
=
await
ExecuteAsync
(
executor
,
obj
);
}
}
return
new
ConsumerExecutedResult
(
resultObj
,
message
.
Id
,
message
.
CallbackName
);
return
new
ConsumerExecutedResult
(
resultObj
,
message
.
Id
,
message
.
CallbackName
);
}
}
}
}
private
async
Task
<
object
>
ExecuteAsync
(
ObjectMethodExecutor
executor
,
object
@class
)
private
async
Task
<
object
>
ExecuteAsync
(
ObjectMethodExecutor
executor
,
object
@class
)
{
{
if
(
executor
.
IsMethodAsync
)
if
(
executor
.
IsMethodAsync
)
{
{
return
await
executor
.
ExecuteAsync
(
@class
);
return
await
executor
.
ExecuteAsync
(
@class
);
}
}
return
executor
.
Execute
(
@class
);
return
executor
.
Execute
(
@class
);
}
}
private
async
Task
<
object
>
ExecuteWithParameterAsync
(
ObjectMethodExecutor
executor
,
private
async
Task
<
object
>
ExecuteWithParameterAsync
(
ObjectMethodExecutor
executor
,
object
@class
,
string
parameterString
)
object
@class
,
string
parameterString
)
{
{
var
firstParameter
=
executor
.
MethodParameters
[
0
];
var
firstParameter
=
executor
.
MethodParameters
[
0
];
try
try
{
{
var
binder
=
_modelBinderFactory
.
CreateBinder
(
firstParameter
);
var
binder
=
_modelBinderFactory
.
CreateBinder
(
firstParameter
);
var
bindResult
=
await
binder
.
BindModelAsync
(
parameterString
);
var
bindResult
=
await
binder
.
BindModelAsync
(
parameterString
);
if
(
bindResult
.
IsSuccess
)
if
(
bindResult
.
IsSuccess
)
{
{
if
(
executor
.
IsMethodAsync
)
if
(
executor
.
IsMethodAsync
)
{
{
return
await
executor
.
ExecuteAsync
(
@class
,
bindResult
.
Model
);
return
await
executor
.
ExecuteAsync
(
@class
,
bindResult
.
Model
);
}
}
return
executor
.
Execute
(
@class
,
bindResult
.
Model
);
return
executor
.
Execute
(
@class
,
bindResult
.
Model
);
}
}
throw
new
MethodBindException
(
throw
new
MethodBindException
(
$"Parameters:
{
firstParameter
.
Name
}
bind failed! ParameterString is:
{
parameterString
}
"
);
$"Parameters:
{
firstParameter
.
Name
}
bind failed! ParameterString is:
{
parameterString
}
"
);
}
}
catch
(
FormatException
ex
)
catch
(
FormatException
ex
)
{
{
_logger
.
ModelBinderFormattingException
(
executor
.
MethodInfo
?.
Name
,
firstParameter
.
Name
,
parameterString
,
_logger
.
ModelBinderFormattingException
(
executor
.
MethodInfo
?.
Name
,
firstParameter
.
Name
,
parameterString
,
ex
);
ex
);
return
null
;
return
null
;
}
}
}
}
}
}
}
}
\ No newline at end of file
test/DotNetCore.CAP.Test/ConsumerInvokerTest.cs
0 → 100644
View file @
9d37dc7f
using
System
;
using
System.Reflection
;
using
System.Threading.Tasks
;
using
DotNetCore.CAP.Abstractions
;
using
DotNetCore.CAP.Infrastructure
;
using
DotNetCore.CAP.Models
;
using
Microsoft.Extensions.DependencyInjection
;
using
Microsoft.Extensions.Logging
;
using
Microsoft.Extensions.Logging.Abstractions
;
using
Moq
;
using
Xunit
;
namespace
DotNetCore.CAP.Test
{
public
class
ConsumerInvokerTest
{
private
ILoggerFactory
_loggerFactory
;
private
Mock
<
IMessagePacker
>
_mockMessagePacker
;
private
Mock
<
IModelBinderFactory
>
_mockModelBinderFactory
;
private
MessageContext
_messageContext
;
public
ConsumerInvokerTest
()
{
_loggerFactory
=
new
NullLoggerFactory
();
_mockMessagePacker
=
new
Mock
<
IMessagePacker
>();
_mockModelBinderFactory
=
new
Mock
<
IModelBinderFactory
>();
}
private
Internal
.
DefaultConsumerInvoker
InitDefaultConsumerInvoker
(
IServiceProvider
provider
)
{
var
invoker
=
new
Internal
.
DefaultConsumerInvoker
(
_loggerFactory
,
provider
,
_mockMessagePacker
.
Object
,
_mockModelBinderFactory
.
Object
);
var
message
=
new
CapReceivedMessage
{
Id
=
SnowflakeId
.
Default
().
NextId
(),
Name
=
"test"
,
Content
=
DateTime
.
Now
.
ToString
(),
StatusName
=
StatusName
.
Scheduled
,
Group
=
"Group.Test"
};
_mockMessagePacker
.
Setup
(
x
=>
x
.
UnPack
(
It
.
IsAny
<
string
>()))
.
Returns
(
new
CapMessageDto
(
message
.
Content
));
_messageContext
=
new
MessageContext
{
Group
=
message
.
Group
,
Name
=
message
.
Name
,
Content
=
Helper
.
ToJson
(
message
)
};
return
invoker
;
}
[
Fact
]
public
async
Task
CanInvokeServiceTest
()
{
var
services
=
new
ServiceCollection
();
services
.
AddSingleton
<
ITestService
,
TestService2
>();
services
.
AddSingleton
<
ITestService
,
TestService
>();
var
provider
=
services
.
BuildServiceProvider
();
var
invoker
=
InitDefaultConsumerInvoker
(
provider
);
var
descriptor
=
new
ConsumerExecutorDescriptor
{
ServiceTypeInfo
=
typeof
(
ITestService
).
GetTypeInfo
(),
ImplTypeInfo
=
typeof
(
TestService
).
GetTypeInfo
(),
MethodInfo
=
typeof
(
TestService
).
GetMethod
(
"Index"
)
};
descriptor
.
Attribute
=
descriptor
.
MethodInfo
.
GetCustomAttribute
<
TopicAttribute
>(
true
);
var
context
=
new
Internal
.
ConsumerContext
(
descriptor
,
_messageContext
);
var
result
=
await
invoker
.
InvokeAsync
(
context
);
Assert
.
NotNull
(
result
);
Assert
.
NotNull
(
result
.
Result
);
Assert
.
Equal
(
"test"
,
result
.
Result
.
ToString
());
}
[
Fact
]
public
async
Task
CanInvokeControllerTest
()
{
var
services
=
new
ServiceCollection
();
var
provider
=
services
.
BuildServiceProvider
();
var
invoker
=
InitDefaultConsumerInvoker
(
provider
);
var
descriptor
=
new
ConsumerExecutorDescriptor
{
ServiceTypeInfo
=
typeof
(
HomeController
).
GetTypeInfo
(),
ImplTypeInfo
=
typeof
(
HomeController
).
GetTypeInfo
(),
MethodInfo
=
typeof
(
HomeController
).
GetMethod
(
"Index"
)
};
descriptor
.
Attribute
=
descriptor
.
MethodInfo
.
GetCustomAttribute
<
TopicAttribute
>(
true
);
var
context
=
new
Internal
.
ConsumerContext
(
descriptor
,
_messageContext
);
var
result
=
await
invoker
.
InvokeAsync
(
context
);
Assert
.
NotNull
(
result
);
Assert
.
NotNull
(
result
.
Result
);
Assert
.
Equal
(
"test"
,
result
.
Result
.
ToString
());
}
}
public
class
HomeController
{
[
CapSubscribe
(
"test"
)]
public
string
Index
()
{
return
"test"
;
}
}
public
interface
ITestService
{
}
public
class
TestService
:
ITestService
,
ICapSubscribe
{
[
CapSubscribe
(
"test"
)]
public
string
Index
()
{
return
"test"
;
}
}
public
class
TestService2
:
ITestService
{
[
CapSubscribe
(
"test"
)]
public
string
Index
()
{
return
"test2"
;
}
}
public
class
CapSubscribeAttribute
:
TopicAttribute
{
public
CapSubscribeAttribute
(
string
name
)
:
base
(
name
)
{
}
}
}
\ No newline at end of file
test/DotNetCore.CAP.Test/SubscribeFinderTest.cs
deleted
100644 → 0
View file @
a7080292
using
System
;
using
DotNetCore.CAP.Abstractions
;
using
Microsoft.Extensions.DependencyInjection
;
using
Xunit
;
namespace
DotNetCore.CAP.Test
{
public
class
SubscribeFinderTest
{
private
IServiceProvider
_provider
;
public
SubscribeFinderTest
()
{
var
services
=
new
ServiceCollection
();
services
.
AddScoped
<
ITestService
,
TestService
>();
services
.
AddCap
(
x
=>
{
});
_provider
=
services
.
BuildServiceProvider
();
}
[
Fact
]
public
void
CanFindControllers
()
{
}
[
Fact
]
public
void
CanFindSubscribeService
()
{
var
testService
=
_provider
.
GetService
<
ICapSubscribe
>();
Assert
.
NotNull
(
testService
);
Assert
.
IsType
<
TestService
>(
testService
);
}
}
public
class
HomeController
{
}
public
interface
ITestService
{
}
public
class
TestService
:
ITestService
,
ICapSubscribe
{
[
CapSubscribe
(
"test"
)]
public
void
Index
()
{
}
}
public
class
CapSubscribeAttribute
:
TopicAttribute
{
public
CapSubscribeAttribute
(
string
name
)
:
base
(
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