我有一个简单的项目来尝试Mediatr问题。当我的API的SAME项目中的处理程序的具体类起作用时,它将起作用。但是,当我将该处理程序类带入另一个项目(并且API引用该项目的c)时,它不会解析注册表。
我收到此错误:
我在我的项目中有这个结构,并且还显示了它的工作原理和不工作的地方:
有关更多说明,请参见以下代码:
MyApi2-> Startup.cs:
namespace MyApi2
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddMediatR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
}
MyApi2-> ValuesController:
namespace MyApi2.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly IMediator _mediator;
public ValuesController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public async Task<IEnumerable<string>> Get()
{
try
{
var rr = await _mediator.Send(new GetTokenModelRequest());
}
catch (Exception ex)
{
throw;
}
return new string[] { "value1", "value2" };
}
}
}
MyBiz-> GetTokenModelRequest
namespace MyBiz
{
public class GetTokenModelRequest : LoginModel, IRequest<TokenModel>
{
}
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
public class TokenModel
{
#region Properties
public Guid Id { get; set; }
public string Username { get; set; }
public string Token { get; set; }
public DateTime Expiration { get; set; }
#endregion
}
}
MyInftra-> TokenQueryHandler
namespace MyInfra
{
public class TokenQueryHandler : ITokenQueryHandler
{
public Task<TokenModel> Handle(GetTokenModelRequest request, CancellationToken cancellationToken)
{
return Task.FromResult(new TokenModel());
}
}
}
因此,如果我从
TokenQueryHandler
到MyInfra
进行 MOVE MyApi
正常工作,但我应该可以将其引用为项目,对不对? 最佳答案
更新
从7.0.0软件包的MediatR.Extensions.Microsoft.DependencyInjection版本开始,调用AppDomain
扩展方法时,不再自动扫描AddMediatR()
以查找包含要注册的MediatR基本类型的已加载程序集。
实际上,该功能的无参数重载已从包中完全消除,需要用户传递程序集(或类型)来进行扫描。
这使得在每个引用的程序集中注册MediatR基本类型(IRequestHandler
,INotificationHandler
,IRequestPreProcessor
和IRequestPostProcessor
),由用户控制和自由决定。
因此,如果我们想在MediatR容器中注册的虚构程序Assembly1
和Assembly2
中有一些MediatR基本类型:
而不是:services.AddMediatR();
您需要做:services.AddMediatR(typeof(Assembly1), typeof(Assembly2));
这使我的原始答案(下)对于使用此软件包的版本7(或更高版本)的任何人都是多余的,但对于使用较旧版本的用户,我将保留在这里。
原始答案
注意:以下答案仅与ojit_a软件包的
对AddMediatR()
文件中的startup.cs
扩展方法的调用完成了初始化MediatR的许多工作:
IRequestHandler
,INotificationHandler
,IRequestPreProcessor
和IRequestPostProcessor
)继承的每个类考虑到以上几点,理解.NET CLR如何加载引用的程序集很重要。 Rick Strahl有一个非常有趣的MediatR.Extensions.Microsoft.DependencyInjection进入细节,但在这里我将用引号进行总结:
为什么要知道这一点很重要?
好吧,在
MyApi2
项目中,您引用了MyInfra
项目,但是实际上并没有以任何方式使用它。这意味着程序集将不会被CLR加载,因此MediatR将无法在App Domain当前加载的程序集中找到它。结果,您的IRequestHandler
将不会被注册(该项目中也不会注册任何其他MediatR基本类型)。解决此问题的方法是确保在对
AddMediatR()
的调用之前,将包含希望注册到MediatR容器中的类型的程序集加载到中。您可以执行以下任一操作:
MyInfra
项目MyApi2
项目中的类型/函数后一个选项是最典型的选项,因为您通常会在要调用的引用程序集中拥有一些功能(而不是仅具有包含类型的程序集)。
无论使用哪种选择,请确保在添加MediatR之前都已执行此操作。否则,您将遇到相同的问题。
关于c# - 当实体位于不同的项目中时,Mediatr为什么不解析方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55337259/