我有一个装饰器和一个相关的服务,看起来像这样:
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,所以不是每个可能的结果都有一个相关的AdditionalDataService实现。如果我试图在没有为对应的Type提供有效的AdditionalDataService实现的情况下使用该装饰器,Simple Injector会抛出异常。
我需要简单注入器做什么-仅为AdditionalDataService -是,如果它没有找到一个实现为相应的类型注入"null"。从那里,我可以在调用服务之前测试null。
我的问题是
我如何告诉简单注入器在遇到未注册的服务请求时注入null,而不是抛出异常?
你应该永远不要将null
注入到你的应用组件的构造函数中。这是一种不好的做法,因为它会使null检查的代码变得复杂。组件应该总是能够假设它获得了一个值。正因为如此,简单注入器的构建使得它(几乎)不可能注入null
值到构造函数中。
相反,您应该使用众所周知的空对象模式,这就是@manji所指的。但是,除了使用ResolveUnregisteredType
事件之外,还有一种更简单的方法可以做到这一点。
我假设您使用Register
注册IAdditionalDataService<TResult, TModel>
实现,就像这样:
// 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<,>));
。
您可以创建一个 'EmptyAdditionalDataService'
(什么都不做),并使用Container将其返回给未注册的服务。ResolveUnregisteredType事件。
你可以在Handled
方法中检查它是否是EmptyAdditionalDataService
的一个实例