I`m using .NET Core 3.1 and I for every request I need to access some of the logged User claims and pass it to business service (another class library) outside the API project.
I`ve tried to create UserService:
public class UsersService
{
private readonly IHttpContextAccessor _context;
public UsersService(IHttpContextAccessor context)
{
_context = context;
}
public UserSession GetUser()
{
return new UserSession()
{
UserDisplayName = _context.HttpContext.User?.Identity?.Name,
};
}
}
and in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
which should be used/injected by other business services or repositories like that:
public class ExampleBusinessService
{
private readonly IUnitOfWork _unitOfWork;
private IUsersService _userService;
public ExampleBusinessService(IUnitOfWork unitOfWork, IUsersService userService)
{
this._unitOfWork = unitOfWork;
this._userService = userService;
}
However it seems I cannot access IHttpContextAccessor outside of the Web project.
Can this be achieved?
Ofcourse I cannot create the UserService in the API and then use it in other libraries cause that mens the libraries should have reference to the web project.
If not is it possible in controller for the startup class to take the needed info from current user and pass it to the services? Or do so in the controller somehow? As is say i need custom class with information taken from the logged user in business services (seprate class library) and repositories (seprate class library)
this is how the solution looks like i need to access the logged user info (custom UserSession class) in BusinessServices library:
Thanks
The IHttpContextAccessor
type is part of the ASP.NET Core framework and as such only available in your web project. If you have your UsersService
implementation in a different project, then you won’t be able to reference the context accessor correctly.
A good way to solve this is to split the contract from the implementation: Define a IUsersService
within your library project and only reference that for your business logic. Users of the service do not need to know what things an implementation might depend on; they only care that they can use the public interface of this service.
Then in your web project, create an implementation of IUsersService
that uses the IHttpContextAccessor
to access the user information. Since the implementation lives within the web project, it can properly access the context accessor.
Finally, combine the interface and the implementation by registering your service implementation as part of your web application:
services.AddTransient<IUsersService, UsersService>();
Once your services (outside of the web project) now require the IUsersService
, they will get the implementation that uses the context accessor to access the user information and everything should work without you having to add a reference to the ASP.NET Core framework in your (otherwise unrelated) libraries.