A user ID is injected into a service in another .dll at run time

Isabella Myers 1 Reputation point
2022-07-30T12:38:38.073+00:00

I am using Unity to do our Dependency Injection.

I would like to inject the users id into the constructor.

Here is my setup:

    private readonly IImportRespository repo;  
    private readonly IUserService userService;  

    /// <summary>  
    /// Initializes a new instance of the <see cref="ImportService" /> class.  
    /// </summary>  
    /// <param name="repo">The repo.</param>  
    /// <param name="userService">The user service.</param>  
    /// <param name="userRequestUserId">The user request user identifier.</param>  
    public ImportService(IImportRespository repo, IUserService userService, int userRequestUserId)  
    {  
        this.repo = repo;  
        this.userService = userService;  
        UserRequestingId = userRequestUserId;  
    }  

Here is how I'm registering in my global.asax file:

public class ImportDIRegistration  
{  
    /// <summary>  
    /// Imports the di registration types.  
    /// </summary>  
    /// <param name="services">The services.</param>  
    public void ImportDIRegistrationTypes(ref UnityContainer services)  
    {  
        var loggedInUser = -1;  

        if (HttpContext.Current != null && HttpContext.Current.User != null)  
        {  
            loggedInUser = HttpContext.Current.User.Identity.TheUserId;  
        }  

        services.RegisterFactory<ImportContextModel>(x =>  
        {  
            return new ImportContextModel(loggedInUser);  
        });  

        services.RegisterType<IImporterUtilities, ImporterUtilities>();  
        services.RegisterType<IImportService, ImportService>();  
        services.RegisterType<IImportRespository, ImportRepository>();  
    }  
}  

So

IImportRespository repo, IUserService userService
Will be injected via the normal process, but I would like the loggedInUserId to be injected as well.

Before DI, I would just instantiate the ImportService and then it would inject it in that way via the constructor.

I've tried something like this:

        var loggedInUser = -1;  

        if (HttpContext.Current != null && HttpContext.Current.User != null)  
        {  
            loggedInUser = HttpContext.Current.User.Identity.TheUserId;  
        }  

        services.RegisterFactory<ImportContextM[o][3]del>(x =>  
        {  
            return new ImportContextModel(loggedInUser);  
        });  

I guess my question is:

Can I inject random other values with DI as long as I have access to them at the start of the application?

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,250 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Lan Huang-MSFT 25,471 Reputation points Microsoft Vendor
    2022-08-01T09:49:37.917+00:00

    Hi @Isabella Myers ,
    loggedInUserId is part of your application's runtime state, so you need to inject it at runtime after a user request starts.
    So the easiest solution is to pass it as a method parameter when requesting the data.
    If you want to create an object that requires runtime parameters, you can use a factory.
    You can drop the act of implementing that factory by either using the Unity version of Typed Factories or let Unity generate factory delegates for you.
    You can check the following documentation for detailed instructions.
    Run-Time Configuration
    https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection
    Dependency Injection Code Smell: Injecting runtime data into components
    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments