MVC 3 / C # Общие мнения о дизайне - PullRequest
0 голосов
/ 06 ноября 2011

Я играю с некоторым кодом и мне нужно мнение по нескольким пунктам.Мне нужно вернуть объект User обратно на мой контроллер из службы аутентификации, которая вводится в контроллер через Ninject.Так что все на одной странице.Вот код контроллера и некоторые служебные коды.

В Login ActionResult для входа в систему я проверяю, существует ли пользователь, и, если он существует, я проверю его подлинность с помощью службы аутентификации.Хорошо, достаточно просто, он возвращает true | false.Я также хочу кое-что еще с пользователем, я уже попал в базу данных, зачем возвращаться и снова ее.Как вы можете видеть в сервисе аутентификации, я настроил хороший пользовательский объект.

Большой вопрос сейчас !!!Должен ли я вернуть пользователя или пользователя.Мои мысли .... я не хочу, чтобы мой контроллер зависел от конкретного пользователя, поэтому я думал соединить IUser с пользователем через ninject и ctor Inject Iuser.Тогда я мог бы установить _user = _authenticationService.AuthenticateUser (userName, password);

Хорошо, плохо, некрасиво ???мысли ???

Код контроллера:

 public class UsersController : Controller
{
    private readonly IUserService _userService;
    private readonly IAuthenticationService _authenticationService;

    public UsersController(IUserService userService,IAuthenticationService authenticationService)
    {
        _userService = userService;
        _authenticationService = authenticationService;
    }

    public ActionResult Login()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Login(UserLoginViewModel userLoginViewModel)
    {
        string userName = userLoginViewModel.UserName;
        string password = userLoginViewModel.Password;

        if (_userService.UserExists(userName))
        {
         //This will change
            if (_authenticationService.AuthenticateUser(userName, password))
            {

            }
        }


        return PartialView("_Login");
    }

    public ActionResult Register()
    {
        return PartialView("_Register");
    }
    [HttpPost]
    public ActionResult Register(UserRegisterViewModel userRegisterViewModel)
    {
        ModelState.AddModelError("UserName", "Testing");
        return PartialView("_Register");
    }
}

Сервисный код:

public class AuthenticationService:IAuthenticationService
{
    private readonly IRepository _repository;
    private readonly IEncryption _encryption;

    public AuthenticationService(IRepository repository,IEncryption encryption)
    {
        _repository = repository;
        _encryption = encryption;
    }

    // HMM! Ok I need to get the User object back to the controller, so instead of returning bool should I return User or IUser.

    public bool AuthenticateUser(string userName, string password)
    {
        try
        {
            var user = _repository.Select<Users>().Where(u => u.UserName == userName).Select(u => new User
            {
                UserId = u.UserID,
                UserTypeId = u.UserTypeID,
                UserName = u.UserName,
                Password = u.Password,
                Salt = u.Salt,
                ActivationCode = u.ActivationCode,
                InvalidLoginAttempts = u.InvalidLoginAttempts,
                IsLockedOut = u.IsLockedOut,
                LastLoginDate = u.LastLoginDate,
                Active = u.Active,
                DateCreated = u.DateCreated,
                LastUpdated = u.LastUpdated
            }).Single();

            // Check the users password hash
            if(_encryption.VerifyHashString(password,user.Password,user.Salt))
            {
                return true;
            }
        }
        catch (Exception)
        {
            return false;

        }
        // get the user from the database




        return false;
    }
}

Ответы [ 2 ]

1 голос
/ 01 декабря 2011

Я бы просто нашел User по имени и проверил пароль с помощью bool AuthenticateUser(User user, string password).Или, если вам нравятся параметры, сделайте это как bool AuthenticateUser(string username, string password, out User user).Я думаю, что метод UserExists бесполезен для этого сценария, так как вы хотите сделать больше с объектом.

0 голосов
/ 01 декабря 2011

Я думаю, что этот другой пост начинает отвечать на ваш вопрос:

Почему бы не использовать контейнер IoC для разрешения зависимостей для сущностей / бизнес-объектов?

По сути, это говоритчто вы могли бы использовать фабричный шаблон вместо DI.

Я также лично добавил бы, что я видел критику этого ранее в списке рассылки Ninject, где упоминалось, что существуют проблемы с производительностью при постоянном разрешении сущностей.через DI.По сути, существует очень много творческих ссылок на каждую сущность в разных сервисах, пользовательском интерфейсе и т. Д .;не говоря уже о преобразовании типов;что ваше приложение получает снижение производительности в виде смерти в результате миллиона сокращений (то есть оно просто разрешает интерфейс так часто, что производительность становится проблемой).Даже если это не было проблемой производительности сейчас, я уверен, что вы хотите, чтобы ваше приложение оставалось масштабируемым в будущем.

Чтобы решить эту проблему производительности DI, вы бы попытались вернуть свою архитектуру обратно к фабрично-ориентированному дизайну.Следовательно, это подразумевает, что фабрика, возможно, является наилучшим кандидатом, в первую очередь, в отличие от использования DI для разрешения сущностей (если для этого не было выгодной причины, которой может не быть).

В итоге:

  • Вероятно, в вашем приложении не должно быть интерфейса IUser.У вашей сущности не должно быть никакой логики, поэтому фактическим типом фактически является контракт, который вы используете.

  • Используйте фабрику для сущностей, без DI.Это даст производительность и масштабируемость производительности.

  • DI по-прежнему полезен, но не рекомендуется для сущностей, если нет веской причины для этого (не могу придумать вескую причину, исходя из моей головы).

  • Обычно DI используется для продвижения контракта, если он требуется.Контракт подразумевается через класс User, так как он не должен содержать логику, тогда как сервис действительно содержит логику и будет отличным кандидатом на DI.Разница в том, что с пользовательской сущностью я могу создавать ее подклассы и создавать разные типы пользователей, а пользовательский класс все еще полезно переопределен, а свойства и т. Д. Повторно использованы, все еще поддерживая контракт, подобный внешнему.С сервисом я не хотел бы иметь конкретную зависимость, где мне пришлось бы переопределять все методы сервиса, так как они, как правило, не будут иметь никакого совместного использования кода, и я, вероятно, не получу повторного использования от существующего сервисаесли бы я должен был написать новую реализацию.

...