我有一个装饰器和一个关联的服务,如下所示:
public interface IAdditionalDataService<TResult, TModel>
{
TResult PopulateAdditionalData(TResult model,
params Expression<Func<TModel, object>>[] properties);
}
public class AdditionalDataDecorator<TQuery, TResult, TModel>
: IQueryHandler<TQuery, TResult>
where TQuery : QueryBase<TResult, TModel>, IQuery<TResult>
where TModel : ModelBase
{
private readonly IQueryHandler<TQuery, TResult> _decorated;
private readonly IAdditionalDataService<TResult, TModel> _additionalDataService;
public AdditionalDataDecorator(IQueryHandler<TQuery, TResult> decorated,
IAdditionalDataService<TResult, TModel> additionalDataService)
{
_decorated = decorated;
_additionalDataService = additionalDataService;
}
public TResult Handle(TQuery query)
{
var result = _decorated.Handle(query);
if (query.RelatedDataProperties != null && query.RelatedDataProperties.Any())
result = _additionalDataService.PopulateAdditionalData(result,
query.RelatedDataProperties.ToArray());
return result;
}
}
装饰器包装了一个查询处理程序,以便结果由 AdditionalDataService
操作,然后返回。
问题不是我的所有查询结果都需要 AdditionalDataService,因此并非每个可能的 TResult 都有关联的 AdditionalDataService 实现。如果我尝试在没有针对相应类型的有效 AdditionalDataService 实现的情况下使用装饰器,则简单注入(inject)器会抛出异常。
我需要 Simple Injector 做的 - 仅适用于 AdditionalDataService - 如果它没有找到相应类型的实现,则注入(inject)“null”。从那里我可以在调用服务之前测试 null。
所以我的问题是
如何告诉 Simple Injector 在遇到对尚未注册的服务的请求时注入(inject) null,而不是抛出异常?
最佳答案
你不应该永远注入(inject)null
进入应用程序组件的构造函数。这是一种不好的做法,因为它会使带有空值检查的代码变得复杂。一个组件应该总是能够假定它获得了一个值。正因为如此,Simple Injector 的构建使其(几乎)无法注入(inject) null
值到构造函数中。
相反,您应该使用众所周知的 Null Object pattern ,这就是@manji 所指的。但不是使用 ResolveUnregisteredType
事件,有一种更简单的方法可以做到这一点。
我假设您注册了您的 IAdditionalDataService<TResult, TModel>
使用 Register
的实现很像这样:
// Simple Injector v3.x
container.Register(typeof(IAdditionalDataService<,>),
new[] { typeof(IAdditionalDataService<,>).Assembly });
// Simple Injector v2.x
container.RegisterManyForOpenGeneric(typeof(IAdditionalDataService<,>),
typeof(IAdditionalDataService<,>).Assembly);
后备注册现在可以注册如下:
// Simple Injector v3.x
container.RegisterConditional(
typeof(IAdditionalDataService<,>),
typeof(EmptyAdditionalDataService<,>),
c => !c.Handled);
// Simple Injector v2.x
container.RegisterOpenGeneric(
typeof(IAdditionalDataService<,>),
typeof(EmptyAdditionalDataService<,>));
就是这样。
关于c# - 如何为未注册的服务注入(inject) null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31600492/