Mig*_*ura 18 c# dependency-injection inversion-of-control asp.net-core
在ASP.NET MVC 5应用程序上,我有以下StructureMap配置:
cfg.For(typeof(IRequestHandler<,>)).DecorateAllWith(typeof(MediatorPipeline<,>));
Run Code Online (Sandbox Code Playgroud)
有谁知道如何使用ASP.NET Core IOC进行此配置?
Tse*_*eng 14
开箱即用的IoC容器不支持装饰模式或自动发现,据我所知,这是"按设计".
我们的想法是提供一个开箱即用的基本IoC结构,或者可以插入其他IoC容器以扩展默认功能.
因此,如果您需要任何高级功能(支持特定构造函数,自动注册实现接口或注入装饰器和拦截器的所有类型),您必须自己编写或使用提供此功能的IoC容器.
services.AddSingleton<IGreeter, Greeter>();
services.Decorate<IGreeter, GreeterLogger>();
services.Decorate<IGreeter, GreeterExceptionHandler>();
Run Code Online (Sandbox Code Playgroud)
顺序很重要。在上面,GreeterLogger 装饰了 Greeter。而 GreeterExceptionHandler 装饰了 GreeterLogger。
小智 5
此解决方法不会将装饰器应用于类型的所有实例,而是使用扩展方法将装饰器逻辑抽象到另一个文件中。
定义装饰器结构,如:
public static class QueryHandlerRegistration
{
public static IServiceCollection RegisterQueryHandler<TQueryHandler, TQuery, TResult>(
this IServiceCollection services)
where TQuery : IQuery<TResult>
where TQueryHandler : class, IQueryHandler<TQuery, TResult>
{
services.AddTransient<TQueryHandler>();
services.AddTransient<IQueryHandler<TQuery, TResult>>(x =>
new LoggingDecorator<TQuery, TResult>(x.GetService<ILogger<TQuery>>(), x.GetService<TQueryHandler>()));
return services;
}
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.RegisterQueryHandler<FindThingByIdQueryHandler, FindThingByIdQuery, Thing>();
Run Code Online (Sandbox Code Playgroud)
还有正在开发的Scrutor包。
在我的博文中,我描述了一个相对简单的扩展方法如何轻松解决这个问题。这是该帖子中的一个示例,它显示了装饰器配置的样子:
services.AddDecorator<IEmailMessageSender, EmailMessageSenderWithRetryDecorator>(decorateeServices =>
{
decorateeServices.AddScoped<IEmailMessageSender, SmtpEmailMessageSender>();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5112 次 |
| 最近记录: |