c# - Autofac and the HttpContext -
i have lot of services require access current user. set principalprovider bound current httpcontext, registered per request once instantiated, never lose context. looks this:
public class principalprovider : iprincipalprovider { // readonly fields private readonly httpcontext _current; /// <summary> /// default constructor /// </summary> public principalprovider() { _current = httpcontext.current; } /// <summary> /// gets current user /// </summary> public iprincipal user => _current?.user; }
and have bound this:
builder.registertype<principalprovider>().as<iprincipalprovider>().instanceperrequest();
now, service has injected should have user exposed. issue have simple. if have controller set this:
public orderscontroller(iorderprovider provider) { _provider = provider; }
that iorderprovider has iprincipleprovider lazily injected it, in case user available because parent service created on controller. issue if isn't injected service, instead used on service injected it. example, have controller:
public userscontroller(iuserprovider provider, iadvancedencryptionstandardprovider encyptionprovider, iphotomanager photomanager) { _userprovider = provider; _encryptionprovider = encyptionprovider; _photomanager = photomanager; }
the iuserprovider doesn't have iprincipalprovider injected it, have service does:
public tropossessionrequest(cormarconfig config, iadvancedencryptionstandardprovider encryptionprovider, lazy<iprincipalprovider> principalprovider) { _config = config; _encryptionprovider = encryptionprovider; _principalprovider = principalprovider; }
the problem here, when tropossessionrequest created, httpcontext not available , therefor null. hoping there way instantiate iprincipleprovider when context becomes available , keep entire request. can every request principalprovider needed.
does know how this?
the simplest way workaround problem access httpcontext.current
in user
accessor:
public iprincipal user => httpcontext.current?.user;
if you're concerned testability, can mock httpcontext.current.user relatively easily.
if you're set on solving using di abstract httpcontext
behind ihttpcontextaccessor
dependency (but since you're still depending on httpcontext
type you'd still in same boat in terms of testing).
public class principalprovider : iprincipalprovider { // readonly fields private readonly ihttpcontextaccessor _httpcontextaccessor; /// <summary> /// default constructor /// </summary> public principalprovider(ihttpcontextaccessor httpcontextaccessor) { _httpcontextaccessor = httpcontextaccessor; } /// <summary> /// gets current user /// </summary> public iprincipal user => _httpcontextaccessor.httpcontext?.user; }
Comments
Post a Comment