c# - How to inject null for unregistered services -
i have decorator , associated service looks this:
public interface iadditionaldataservice<tresult, tmodel> { tresult populateadditionaldata(tresult model, params expression<func<tmodel, object>>[] properties); } public class additionaldatadecorator<tquery, tresult, tmodel> : iqueryhandler<tquery, tresult> tquery : querybase<tresult, tmodel>, iquery<tresult> 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; } }
the decorator wraps query handler results manipulated additionaldataservice
, returned.
the issue not of query results need additionaldataservice, not every possible tresult has associated additionaldataservice implementation. simple injector throws exception if try use decorator without valid additionaldataservice implementation corresponding type.
what need simple injector - additionaldataservice - if doesn't find implementation corresponding type inject "null". there can test null before calling service.
so question is
how can tell simple injector inject null when encounters request service hasn't been registered, instead of throwing exception?
you should never inject null
services. bad practice, because complicates code null checks. component should able assume gets value. because of this, simple injector built make (almost) impossible inject null
values constructors.
instead should use well-known null object pattern, @manji referring to. instead of using resolveunregisteredtype
event, there easier way this.
i assume register iadditionaldataservice<tresult, tmodel>
implementations using register
this:
// simple injector v3.x container.register(typeof(iadditionaldataservice<,>), new[] { typeof(iadditionaldataservice<,>).assembly }); // simple injector v2.x container.registermanyforopengeneric(typeof(iadditionaldataservice<,>), typeof(iadditionaldataservice<,>).assembly);
a fallback registration can registered follows:
// simple injector v3.x container.registerconditional( typeof(iadditionaldataservice<,>), typeof(emptyadditionaldataservice<,>), c => !c.handled); // simple injector v2.x container.registeropengeneric( typeof(iadditionaldataservice<,>), typeof(emptyadditionaldataservice<,>));
that's it.
Comments
Post a Comment