/// <summary>
        /// By introducing an abstract factory that creates the appropairate authenticator and authorizer objects as per the designated user-type, we have factored out that which changes into a component in its own right, and can the more easily maintain it - for example by introducing a new user-type.
        /// </summary>
        public static void Main()
        {
            var basicUser = User.CreateUser("Arnold Schwarzenegger", "IllBeBack", UserTypeEnum.BasicUser);
            ISecurityProviderFactory securityProviderFactory = GetSecurityProviderFactory(basicUser.UserType);
            UserSecurityManager      userSecurityManager     = new UserSecurityManager(securityProviderFactory);

            userSecurityManager.PerformUserSecurityOperations(basicUser);

            var superUser = User.CreateUser("Clint Eastwood", "MakeMyDayPunk", UserTypeEnum.SuperUser);

            securityProviderFactory = GetSecurityProviderFactory(superUser.UserType);
            userSecurityManager     = new UserSecurityManager(securityProviderFactory);
            userSecurityManager.PerformUserSecurityOperations(basicUser);
        }
 public UserSecurityManager(ISecurityProviderFactory securityProviderFactory)
 {
     _authorizer    = securityProviderFactory.CreateAuthorizer();
     _authenticator = securityProviderFactory.CreateAuthenticator();
 }