jon.r
jon.r

Reputation: 1058

DRY principle with controller methods

I have this logic in several methods in my MVC5 project. It works but I am repeating myself pretty consistently.

private PersonnelManagementEntities db = new PersonnelManagementEntities();
        private ActiveDirectoryTools adt = new ActiveDirectoryTools();
        private ManagerService ms = new ManagerService();
        private UserService us = new UserService();
        private CompanyService cs = new CompanyService();

public ActionResult CompanySummary(int id = 0)
        {
            //Repeating logic begins here
            int setID = 0;
            adt.GetUserInfo(User.Identity.Name);
            //Fetch current users company
            User currentUser = us.getUser(adt.adUserName);
            //Determine if user is a global manager or not. If global display all companies
            ViewBag.Company = cs.FetchCompanies(currentUser);
            //You can only see the companies you're assigned to, in the AllRequests window. Unless manually overwritten in the URL
            if (currentUser.GlobalUser == true && id > 0)
            {
                setID = id;
            }
            else
            {
                setID = (int)currentUser.CompanyID;
            }
            //End of repeating logic
            var resultSet = db.UserTimeSummaryUpdated(setID);
            return View(resultSet.ToList());

        }

What do you guys think would be the best way of reducing the amount of times I repeat this?

You can see here in another method where I reuse this code:

 public ActionResult AllRequests(int id = 0)
        {
            int setID = 0;
            adt.GetUserInfo(User.Identity.Name);
            User currentUser = us.getUser(adt.adUserName);
            ViewBag.Company = cs.FetchCompanies(currentUser);

            //You can only see the companies you're assigned to, in the AllRequests window. Unless manually overwritten in the URL
            if (id > 0)
            {
                setID = id;
            }
            else
            {
                setID = (int)currentUser.CompanyID;
            }

            ViewBag.EmployeeList = db.Users
                                     .Where(x => x.disabled == false)
                                     .Where(x => x.CompanyID == setID)
                                     .OrderBy(x => x.FullName)
                                     .ToList();

            IQueryable timeRequests = db.TimeRequests
                                 .Include(t => t.ApproveDenyReason)
                                 .Include(t => t.DayType)
                                 .Include(t => t.User)
                                 .Include(t => t.User1)
                                 .Include(t => t.User2)
                                 .OrderByDescending(t => t.sDateTime)
                                 .Where(t => t.User.CompanyID == setID);
            return View(timeRequests);
        }

I was thinking about creating an ActionFilter and doing it that way but it seems kind of a hack instead of the correct way of doing things. I also entertained the idea of when a user logs in I create a user object and persist it through a session. Any help is appreciated

Upvotes: 1

Views: 112

Answers (1)

reachingnexus
reachingnexus

Reputation: 101

One option is to write a CustomController that inherits Controller. I did this to add Member Session Data and a Messaging Output System that can write to my LayoutView. For the example below I assumed FetchCompanies returns a list...

public class CustomController : Controller
{
    private ActiveDirectoryTools _adt = new ActiveDirectoryTools();
    private UserService _us = new UserService();
    private CompanyService _cs = new CompanyService();
    public List<Company> UserCompanies;

    public ApplicationController()
        : base()
    { 
     _adt.GetUserInfo(User.Identity.Name);
     User currentUser = _us.getUser(adt.adUserName);
     UserCompanies = _cs.FetchCompanies(currentUser);
    }

}

When you create your Controller inherit from this CustomController. Then in your ActionResult simply set using UserCompanies.

public AccountController:CustomController
{
    public ActionResult Index()
    {
        ViewBag.Company = UserCompanies;
        return View();
    }
}

Upvotes: 1

Related Questions