locked
Injecting a user id into a service in another .dll at run time RRS feed

  • Question

  • User-1188570427 posted

    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<ImportContextModel>(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?

    Thursday, August 20, 2020 9:30 PM

All replies

  • User1120430333 posted

    Why can't you create a class to go read the value from its source, the class uses an interface and the class implements the interface that uses a method in the class to go get the id? You inject that class/object through Unity into the class/object needing the id and execute the method in the injected object to go get the id. It's what OO programming is about.

    Thursday, August 20, 2020 10:04 PM
  • User-1188570427 posted

    DA924

    Why can't you create a class to go read the value from its source, the class uses an interface and the class implements the interface that uses a method in the class to go get the id? You inject that class/object through Unity into the class/object needing the id and execute the method in the injected object to go get the id. It's what OO programming is about.

    Well maybe? May layers of the API (not true web api) might not be set up right?

    We have different APIs that are in different projects/dlls. I want to pass in the user id to one of the side APIs all the time.

    Let me do some research with your comment and I'll let you know. 

    WebApp

    Then I add nugets of:

    Core API

    Import API

    Department API

    Which are all separate .dlls and are developed outside of the WebApp.

    I want to use DI to pass in the user id of the logged in use of the Web App all the time so I do not have to pass it through the parameter list of each method. 

    Friday, August 21, 2020 12:36 AM
  • User-1188570427 posted

    This is similar to what I want to do:

    https://stackoverflow.com/questions/40914634/inject-constructor-parameters-using-unity

    But I'm injecting other Items in as well. 

    Friday, August 21, 2020 1:09 AM
  • User-1188570427 posted
            services.RegisterType<IImportService, ImportService>(new InjectionProperty("UserRequestingId", GetUserId()));

    This seems to work and will set the Property UserRequestingId to whatever you pass it.

    But this code runs BEFORE the user id is set in asp.net Identity so it is set to -1;

    Not sure how to set the DI AFTER the user has logged in and their user id is available?

            private int GetUserId()
            {
                var loggedInUser = -1;
    
                if (HttpContext.Current != null && HttpContext.Current.User != null)
                {
                    loggedInUser = new UserIdentityUtilities().GetUserId(HttpContext.Current.User.Identity);
                }
    
                return loggedInUser;
            }

    So if I set the value to 99:

               services.RegisterType<IImportService, ImportService>(new InjectionProperty("UserRequestingId", 99));

    It will be 99 when my ImportService is called. 

    Friday, August 21, 2020 2:53 AM
  • User-1188570427 posted
                services.RegisterFactory<ImportContextModel>(x =>
                {
                    var loggedInUser = -1;
    
                    if (HttpContext.Current != null && HttpContext.Current.User != null)
                    {
                        loggedInUser = new UserIdentityUtilities().GetUserId(HttpContext.Current.User.Identity);
                    }
    
                    return new ImportContextModel(loggedInUser);
                });

    This is setting the EF context model to do the same thing so that the UserId is available in the DAL layer.

    This way works, but as you can see it is RegisterFactory(...) instead of RegisterType.

    Is there a way to convert a RegisterType to a RegisterFactory?

    Friday, August 21, 2020 2:56 AM
  • User1120430333 posted

    Is there a way to convert a RegisterType to a RegisterFactory?

    I don't think that can be done.

    Friday, August 21, 2020 1:08 PM
  • User784298167 posted

    I want to be that like part of codes for making the https://xxxtentacionmerch.net/  and as well their API's.

    services.RegisterFactory<ImportContextModel>(x =>
                {
                    var loggedInUser = -1;
    
                    if (HttpContext.Current != null && HttpContext.Current.User != null)
                    {
                        loggedInUser = new UserIdentityUtilities().GetUserId(HttpContext.Current.User.Identity);
                    }
    
                    return new ImportContextModel(loggedInUser);
                });
    Sunday, August 23, 2020 9:30 PM