locked
Asp.net web API DI question? RRS feed

  • Question

  • User-1104215994 posted

    Hello,

    I am using basic authentication in my API. I use Unity as DI container. I wonder if this registration is enough for User Validation? Or should I add <g data-gr-id="229" id="229" class="gr_ gr_229 gr-alert gr_gramm Style multiReplace">to</g><g data-gr-id="229" id="229" class="gr_ gr_229 gr-alert gr_gramm gr_disable_anim_appear Style multiReplace"> </g>RegisterType<UnitOfWork>(new HierarchicalLifetimeManager())<g data-gr-id="229" id="229" class="gr_ gr_229 gr-alert gr_gramm gr_disable_anim_appear Style multiReplace"> it</g>?

    public static class UnityConfig
        {
            #region Unity Container
            private static Lazy<IUnityContainer> container =
              new Lazy<IUnityContainer>(() =>
              {
                  var container = new UnityContainer();
                  RegisterTypes(container);
                  return container;
              });
    
            /// <summary>
            /// Configured Unity Container.
            /// </summary>
            public static IUnityContainer Container => container.Value;
            #endregion
    
           
            public static void RegisterTypes(IUnityContainer container)
            {
                
                container.RegisterType<IGameServices, GameServices>().RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());
                container.RegisterType<IUserValidate, UserValidate>();
                
              
            }
        }

    Here is User Validate:

     public class UserValidate : IUserValidate
        {
            private readonly UnitOfWork _unitOfWork;
    
            /// <summary>
            /// Public constructor.
            /// </summary>
            public UserValidate(UnitOfWork unitOfWork)
            {
                _unitOfWork = unitOfWork;
            }
    
            /// <summary>
            /// Public method to authenticate user by user name and password.
            /// </summary>
            /// <param name="userName"></param>
            /// <param name="password"></param>
            /// <returns></returns>
            public async Task<bool> Login(string userName, string password)
            {
                var user = await _unitOfWork.UserRepository.Get(u => u.userName.Equals(userName, StringComparison.OrdinalIgnoreCase) && u.password == password);
                if (user == null) return false;
                return true;
            }
        }

    Friday, July 19, 2019 7:44 AM

Answers

  • User753101303 posted

    So to me it should be :

             
                container.RegisterType<IGameServices, GameServices>().RegisterType<UnitOfWork>(new TransientLifetimeManager());

    so that each controller get its own instance (which seems enough as far as I can see). Later you could change that to scope the DbContext to the http request if this is what you need instead.

    Both Container and Hierachical are creating a singleton (ie create a new object the first time and then returns the same object on subsequent resolves which is a disaster for a DbContext)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, July 23, 2019 4:10 PM

All replies

  • User-474980206 posted

    can not tell without knowing the lifetime requirements of UnitOfWork.  As a UnitOfWork is stored, then UserValidate must match the same lifetime. 

    My guess from your other thread is that you really do not understand the DI lifetime for request objects in asp.net. You should probably switch to DI factories that create one time instances, rather that trying to share single request only instances.

    as asp.net 4.* is thread agile (can switch threads for the same request, or use the same thread for concurrent requests),  it requires using a request context to pass request objects between pipeline events. Async processing in asp.net 4.* has logic to manage the saving and restoring this context between async calls.  Your DI container has to be tied to the request context somehow to create request scoped instances.

    note: asp.net core is slightly different. multiple current requests are handled by the same thread, but a request can not switch threads. this still makes thread local storage useless, and requires the request context (HttpContext) to passed via the pipeline.  

    Friday, July 19, 2019 7:13 PM
  • User753101303 posted

    So to me it should be :

             
                container.RegisterType<IGameServices, GameServices>().RegisterType<UnitOfWork>(new TransientLifetimeManager());

    so that each controller get its own instance (which seems enough as far as I can see). Later you could change that to scope the DbContext to the http request if this is what you need instead.

    Both Container and Hierachical are creating a singleton (ie create a new object the first time and then returns the same object on subsequent resolves which is a disaster for a DbContext)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, July 23, 2019 4:10 PM