Jam*_*mes 8 c# dependency-injection mediatr asp.net-core
我有以下课程
SearchQuery<TEntity>
Run Code Online (Sandbox Code Playgroud)
它与 MediatR 一起在控制器上使用,如下所示:
await Mediator.Send(
new SearchQuery<TEntity>(
new PageInformation(pageNumber, pageSize), Request.Query));
Run Code Online (Sandbox Code Playgroud)
我已在我的应用程序中将 MediatR 注册到服务集合中,如下所示:
services.AddMediatR(Assembly.GetExecutingAssembly());
Run Code Online (Sandbox Code Playgroud)
该类SearchQuery位于正确的命名空间中,它与已创建的所有其他类位于同一位置,但是当我运行该应用程序时,我收到以下错误。
MediatR.IRequestHandler
2[AssetManagement.Core.Application.Search.Queries.SearchQuery1[AssetManagement.Core.Domain.Entities.TEntity]、AssetManagement.Core.Application.Models.PaginatedList`1[AssetManagement.Core.Domain.Entities.TEntity]]。向容器注册您的处理程序。有关示例,请参阅 GitHub 中的示例
SearchQuery<T>详细班级:
public class SearchQuery<T> : IRequest<PaginatedList<T>>
{
public SearchQuery(
PageInformation pageInformation,
IQueryCollection searchQueryCollection)
{
QueryCollection = searchQueryCollection;
PageInformation = pageInformation;
}
public IQueryCollection QueryCollection { get; }
public PageInformation PageInformation { get; }
}
public class SearchQueryHandler<T>
: IRequestHandler<SearchQuery<T>, PaginatedList<T>>
{
private readonly IFormsDbContext _formsContext;
public SearchQueryHandler(IFormsDbContext formsContext)
{
_formsContext = formsContext;
}
public Task<PaginatedList<T>> Handle(
SearchQuery<T> request, CancellationToken cancellationToken)
{
//return PaginatedList<Entity> here?
...
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用服务集合注册类型,如下所示
services.AddTransient(
typeof(IRequestHandler<,>),
typeof(SearchQueryHandler<TEntity>));
Run Code Online (Sandbox Code Playgroud)
但随后收到以下错误:
System.ArgumentException:'开放通用服务类型'MediatR.IRequestHandler`2 [TRequest,TResponse]'需要注册开放通用实现类型
我尝试过各种其他方法来解决这个问题,但我觉得我在兜圈子。
MS.DI 无法实现您想要实现的目标。您正在尝试将开放式通用接口映射IRequestHandler<TRequest, TResponse>到开放式通用实现SearchQueryHandler<T>。但是,根据您所需的映射, 的泛型类型参数IRequestHandler<TRequest, TResponse>(即TRequest和TResponse)并不完全映射到 的泛型类型参数SearchQueryHandler<T>。
当谈到仿制药时,MS.DI 非常简单。为了能够进行映射,MS.DI 必须能够将抽象的通用类型参数直接填充到创建的实现中。为了使其不那么抽象,MS.DI 只需调用.MakeGenericType()类似于以下代码:
Type registeredOpenImplementation = typeof(SearchQueryHandler<>);
Type requestedAbstraction =
typeof(IRequestHandler<SearchQuery<Customer>, PaginatedList<Customer>>);
Type closedImplementationToResolve =
registeredOpenImplementation
.MakeGenericType(requestedAbstraction.GetGenericTypeArguments());
Run Code Online (Sandbox Code Playgroud)
MakeGenericType然而,对 的调用将完全失败,因为:
requestedAbstraction.GetGenericTypeArguments()返回两种类型,而registeredOpenImplementationhas 一种。SearchQueryHandler<T>。哪里SearchQuery<Customer>是从抽象中提取的,SearchQueryHandler<T>期望Customer。长话短说,MS.DI 并不是为您的用例而构建的。您有两个选择:
services.AddTransient<
IRequestHandler<SearchQuery<Customer>, PaginatedList<Customer>>,
SearchQueryHandler<Customer>>();
services.AddTransient<
IRequestHandler<SearchQuery<Order>, PaginatedList<Order>>,
SearchQueryHandler<Order>>();
services.AddTransient<
IRequestHandler<SearchQuery<Product>, PaginatedList<Product>>,
SearchQueryHandler<Product>>();
services.AddTransient<
IRequestHandler<SearchQuery<Employee>, PaginatedList<Employee>>,
SearchQueryHandler<Employee>>();
// etc
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6204 次 |
| 最近记录: |