0

I've been brooding over a design issue (smelly code kinda thing) for a couple days now. Maybe you can help.

I have a "Login" Method in my RegistrationService, and currently it looks simplified like this:

public Boolean Login(String username, String password, 
                     out String successRedirectUrl, 
                     out IValidationDictionary validationResults)
{
    successRedirectUrl = "";
    if (!Validator.IsValid(username) || !Validator.IsValid(password)) return false;

    // Other logic
    // Distributed login requests etc.
    // Build Redirect Url if login was successful etc.
}

Okay, let me explain above code. The method's main return value (Boolean) is supposed to tell the caller whether or not the login request was successful. Now, IF it was successful, I need to redirect the user to a different Url (thus, the "out" parameter successRedirectUrl). If it was NOT successful, I need to tell the user in the view what was wrong - thus the ValidationDictionary (Modelstate).

This code is really ugly and hard to maintain though. I thought of getting rid of the Boolean return type (returning the successRedirectUrl directly and checking on the caller side if it is empty) but I felt things became even more unclear.

Any idea how to do this better?

Thank you!

1
  • 1
    I really think you mean: s/breeding/brooding. Breeding is something else entirely ;) . In fact, there you go- fixed it for you. Commented Aug 15, 2009 at 20:03

3 Answers 3

9

Make a custom class to hold all three values, and return it. Get rid of the "out" parameters.

Sign up to request clarification or add additional context in comments.

Comments

3

How about this??

public class LoginOutput{

private bool _isLoginSuccess=false;
public bool IsLoginSuccess{/*Usual get set block*/}

private string _successRedirectUrl = String.Empty();
public string SuccessRedirectUrl{/*Usual get set block*/}

public IValidationDictionary ValidationResultDict{/*Usual get set block*/}
}

//your method now could be

public LoginOutput Login(string username, string password){
// your logic goes here
}

1 Comment

you could handle the dictionary stuff by refactoring that part in another method..would be more testable
1

Questions:

Is the redirect URL different for different users? - I would say it shouldn't be, but if it is different, the decision shouldn't be in your business layer. This is UI logic and should be there.

What's your IValidationDictionary interface? You can probably just use it directly in your UI logic:

public IValidationDictionary Login(string user, string password);

var user = "bob";
var validator = Login(user, "password");

if (validator.IsValid)
    Response.Redirect(GetUserPage(user));
else
    HandleLoginError();

Note that GetUserPage() should not be a database lookup or anything else complicated. Again, this should be simple UI logic, something like:

public string GetUserPage(string user)
{
    return "/MyPage/" + user;
}

1 Comment

Yes, the redirect URL is different for different users.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.