Избегайте избыточности в нескольких контроллерах в коде C# - PullRequest
0 голосов
/ 22 марта 2020

Я пишу приложение, которое вставляет данные в 6 различных баз данных. Каждая база данных имеет свою модель, контроллер и представления.

Проблема в том, что все они имеют одни и те же методы с небольшой разницей, но в целом они все одинаковые. Это избыточность и много похожего кода в каждом контроллере.

Есть ли способ уменьшить это? Не могли бы вы предложить шаблон проектирования, чтобы изучить его, чтобы реализовать его здесь, потому что я чувствую, что я делаю здесь, это плохая практика программирования?

Я прав или просто параноик? Спасибо

контроллер 1:

namespace Manage_account.Controllers
{
    public class HRLoanController : Controller
    {

        private Entities db = new Entities();

        string EmployeeLogin = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\')[1];

        [HttpGet]
        public ActionResult Create()
        {
            ViewBag.DepID = new SelectList(db.Departments , "DepID", "Department1");
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(AccountVM vM)
        {
            if (ModelState.IsValid)
            {
                #region Insert in account and lob of HRLoan database
                var chk_accountName = db.Accounts.Any(x => x.AccountName == vM.Accountex.Name);
                try
                {
                    if (!chk_accountName)
                    {
                        Account account = new Account();
                        account.AccountName = vM.Accountex.Name;
                        account.IsActive = true;
                        db.Accounts.Add(account);
                        db.SaveChanges();
                        TempData["success"] = "account saved successfully !";

                    }
                    else
                    {
                        TempData["warning"] = "Data already exists";
                    }

                    var Find_AccountId = db.Accounts.Where(x => x.AccountName == vM.Accountex.Name).FirstOrDefault();
                    var theID = Find_AccountId.AccountID;
                    var chk_lobName = db.LOBs.Where(x => x.AccountID == theID).Any(x => x.LOB1 == vM.LOBex.Name);
                    if (!chk_lobName)
                    {
                        LOB oB = new LOB();
                        oB.LOB1 = vM.LOBex.Name;
                        oB.LOBValue = vM.LOBex.Name;
                        oB.IsActive = true;
                        oB.AccountID = theID;
                        oB.DEPID = vM.Accountex.Dep_ID;
                        db.LOBs.Add(oB);
                        db.SaveChanges();
                        TempData["success"] = "lob saved successfully !";
                    }
                    else
                    {
                        TempData["warning"] = "Data already exists";
                    }

                }
                catch
                {
                    TempData["error"] = "Something went wrong :( .Please, try again later.";
                }

                #endregion
            }

            return RedirectToAction("Create");

        }

        public ActionResult CreateLob()
        {
            ViewBag.DepID = new SelectList(db.Departments, "DepID", "Department1");
            ViewBag.AccountID = new SelectList(db.Accounts.OrderBy(x=>x.AccountName), "AccountID" , "AccountName");
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateLob(LOBex lOBex)
        {
            #region insert in Lob table in HRLoan database 
            if (ModelState.IsValid)
            {
                try
                {
                    var chk_LobName = db.LOBs.Where(x => x.AccountID == lOBex.Account_ID).Any(x => x.LOB1 == lOBex.Name);
                    if (!chk_LobName)
                    {
                        LOB oB = new LOB();
                        oB.LOB1 = lOBex.Name;
                        oB.LOBValue = lOBex.Name;
                        oB.IsActive = true;
                        oB.DEPID = lOBex.DEPID;
                        oB.AccountID = lOBex.Account_ID;
                        db.LOBs.Add(oB);
                        db.SaveChanges();
                        TempData["success"] = "Data saved to LOB Table !";
                    }
                    else
                    {
                        TempData["warning"] = "Data already exists !";
                    }

                }
                catch
                {
                    TempData["danger"] = "Something went wrong :(. Please, try again later.";
                }

            }
            return RedirectToAction("CreateLob");
            #endregion

        }

        [HttpGet]
        public ActionResult CreateUser()
        {
            ViewBag.RoleID = new SelectList(db.Roles.OrderBy(x => x.Role1), "RoleID", "Role1");
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateUser(AddUser addUser)
        {
            #region Insert new user in Users table in HRLoan database 
            if (ModelState.IsValid)
            {

                var chk_user_existence = db.Users.Any(x => x.UserID == addUser.UserID); //check if user exists in db or not
                if (!chk_user_existence)
                {
                    User user = new User();
                    user.UserID = addUser.UserID;
                    user.UserName = addUser.UserName;
                    user.UserEmail = addUser.UserEmail;
                    user.IsActive = true;
                    user.InsertedOn = DateTime.Now;
                    user.UpdatedBy = EmployeeLogin;
                    user.GradeID = addUser.GradeID;
                    user.RoleID = addUser.RoleID;
                    db.Users.Add(user);
                    db.SaveChanges();
                }
                else
                {
                    TempData["warning"] = "This user already exists in Users table !";
                }
            }
            else
            {
                TempData["error"] = "Something went wrong :/ . Please, try again later!";
            }

            return RedirectToAction("CreateUser");
            #endregion
        }

        [HttpGet]
        public ActionResult CreateBoss_Department()
        {
            var get_Admin = db.Users.Where(x => x.RoleID == 1).Where(x=>x.IsActive==true).ToList();
            ViewBag.UserID = new SelectList(get_Admin.OrderBy(x=>x.UserName) , "UserID", "UserName");
            ViewBag.Indexs = new SelectList(db.LOBs , "Indexs", "LOB1");
            ViewBag.AccountID = new SelectList(db.Accounts.OrderBy(x=>x.AccountName) , "AccountID", "AccountName");
            return View();
        }

        #region populate user's ID with their specified names 

        //populate user's names
        public JsonResult GetUserName_toUserLogin(string usr)
        {
            List<User> getUser = new List<User>();
            getUser = (from r in db.Users where (r.UserID == usr) select r).ToList();
            List<SelectListItem> User_ID = new List<SelectListItem>();

            foreach (User name in getUser)
            {
                User_ID.Add(new SelectListItem { Text = name.UserID, Value = name.UserName.ToString() });
            }
            return Json(new SelectList(User_ID, "Value", "Text"));

        }
        #endregion

        #region Populates Lobs according to the selected account in the Create boss-department view 
        //populate Lobs
        public JsonResult GetLOB_toAccount(int acc)
        {
            List<LOB> getLob = new List<LOB>();
            getLob = (from r in db.LOBs where (r.AccountID == acc) select r).ToList();
            List<SelectListItem> Lobs = new List<SelectListItem>();

            foreach (LOB lob in getLob)
            {
                Lobs.Add(new SelectListItem {Text = lob.LOB1, Value = lob.Indexs.ToString() });
            }
            return Json(new SelectList(Lobs , "Value" , "Text"));
        }
        #endregion



        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateBoss_Department(Boss_Dep boss_Dep)
        {
            #region Insert new record for admins only in Boss_Deapartment table in HRLoan database 




            if (ModelState.IsValid)
            {
                var Chk_UsrAccess = db.Boss_Department.Where(x => x.BossLogin == boss_Dep.BossLogin).Any(x => x.LOBIndexs == boss_Dep.LOBIndexs);
                if (!Chk_UsrAccess)
                {
                    Boss_Department boss_ = new Boss_Department();
                    boss_.BossLogin = boss_Dep.BossLogin;
                    boss_.LOBIndexs = boss_Dep.LOBIndexs;
                    boss_.IsActive = true;
                    boss_.ToMail = boss_Dep.To_mail;
                    boss_.InsertedOn = DateTime.Now;
                    boss_.UpdatedBy = EmployeeLogin;
                    db.Boss_Department.Add(boss_);
                    db.SaveChanges();
                    TempData["success"] = "Data saved successfully !";
                }
                else
                {
                    TempData["warning"] = "Data already exists in Boss_Department table !";
                }

            }
            else
            {
                TempData["error"] = "something went wrong :( !";
            }

            return RedirectToAction("CreateBoss_Department");
            #endregion

        }





        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

контроллер 2:

namespace Manage_account.Controllers
{
    public class HrperonalController : Controller
    {
        private personal personal = new personal();

        string EmployeeLogin = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\')[1];


        //GET: create
        [HttpGet]
        public ActionResult Create()
        {
            ViewBag.DepID = new SelectList(personal.Departments, "DepID", "Department");
            return View();
        }


        //POST: create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(AccountVM vM)
        {
            if (ModelState.IsValid)
            {
                #region insert account in account table in HRPersonnal db
                var chk_accountName = personal.Accounts.Any(x => x.AccountName == vM.Accountex.Name);
                if (!chk_accountName)
                {
                    Accounts accounts = new Accounts();
                    accounts.AccountName = vM.Accountex.Name;
                    accounts.IsActive = true;
                    personal.Accounts.Add(accounts);
                    personal.SaveChanges();
                    TempData["success"] = "Account has been saved successfully :) !";
                }
                else
                {
                    TempData["warning"] = "account already exists";
                }
                #endregion

                #region insert Lob under that account in LOB table in HRPersonnal db
                var Added_account = personal.Accounts.Where(x=>x.AccountName == vM.Accountex.Name).FirstOrDefault().AccountID;
                var chk_lobName = personal.LOB.Where(x => x.DEPID == vM.LOBex.DEPID)
                    .Where(x => x.AccountID == Added_account).Any(x => x.LOB1 == vM.LOBex.Name);
                if (!chk_lobName)
                {
                    LOB lOB = new LOB();
                    lOB.LOB1 = vM.LOBex.Name;
                    lOB.LOBValue = vM.LOBex.Name;
                    lOB.AccountID = Added_account;
                    lOB.DEPID = vM.LOBex.DEPID;
                    lOB.IsActive = true;
                    personal.LOB.Add(lOB);
                    personal.SaveChanges();
                    TempData["success"] = "Lob has been saved successfully :) !";
                }
                else
                {
                    TempData["warning"] = "Lob already exists on that account";
                }
                #endregion
            }
            else
            {
                TempData["error"] = "Something went wrong.Please, try again later :/.";
            }
            return RedirectToAction("Create");
        }


        //GET: createLob
        [HttpGet]
        public ActionResult CreateLob()
        {
            ViewBag.AccountID = new SelectList(personal.Accounts, "AccountID", "AccountName");
            ViewBag.DepID = new SelectList(personal.Departments , "DepID", "Department");
            return View();
        }


        //POST: createLob
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateLob(LOBex oBex)
        {
            #region insert Lob in LOB table in HRPersonnal db
            if (ModelState.IsValid)
            {
                var chk_Lob = personal.LOB.Where(x => x.DEPID == oBex.DEPID).Where(x => x.AccountID == oBex.Account_ID).Any(x=>x.LOB1 == oBex.Name);
                if (!chk_Lob)
                {
                    LOB lOB = new LOB();
                    lOB.LOB1 = oBex.Name;
                    lOB.LOBValue = oBex.Name;
                    lOB.DEPID = oBex.DEPID;
                    lOB.AccountID = oBex.Account_ID;
                    lOB.IsActive = true;
                    personal.LOB.Add(lOB);
                    personal.SaveChanges();
                    TempData["success"] = "Lob has been saved successfully :) ! ";
                }
                else
                {
                    TempData["warning"] = "Lob already exists !";
                }

            }
            #endregion
            else
            {
                TempData["error"] = "Something went wrong.Please, try again later :/ !";
            }
            return RedirectToAction("CreateLob");
        }


        //GET: createuser
        [HttpGet]
        public ActionResult CreateUser()
        {
            ViewBag.RoleID = new SelectList(personal.Roles , "RoleID", "Role");
            ViewBag.DepID = new SelectList(personal.Departments, "DepID", "Department");
            return View();
        }


        //POST: createuser
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateUser(PersonnalUser user)
        {
            if (ModelState.IsValid)
            {
                var chk_user = personal.Users.Any(x => x.UserID == user.usrID);
                if (!chk_user)
                {
                    Users usr = new Users();
                    usr.UserID = user.usrID;
                    usr.UserName = user.Name;
                    usr.RoleID = user.Roleid;
                    usr.IsActive = true;
                    usr.GradeID = user.Gradeid;
                    usr.InsertedBy = EmployeeLogin;
                    usr.InsertedOn = DateTime.Now;
                    usr.Email = user.Email;
                    usr.PositionName = user.PositionName;
                    usr.DepartmentName = user.DepartmentName;
                    personal.Users.Add(usr);
                    personal.SaveChanges();
                    TempData["success"] = "User has been saved successfully :) !";
                }
                else
                {
                    TempData["warning"] = "User already exists !";
                }
            }

            return RedirectToAction("CreateUser");
        }


        //GET: create boss-department
        [HttpGet]
        public ActionResult CreateBoss_Dep()
        {
            var get_this_Admin = personal.Users.Where(x => x.RoleID == 1).Where(x => x.IsActive == true).ToList();
            ViewBag.UserID = new SelectList(get_this_Admin.OrderBy(x => x.UserName), "UserID", "UserName");
            ViewBag.Indexs = new SelectList(personal.LOB, "Indexs", "LOB1");
            ViewBag.AccountID = new SelectList(personal.Accounts, "AccountID", "AccountName");
            return View();
        }


        #region populate user's ID with their specified names 

        //populate user's names
        public JsonResult GetUserName_toUserLogin(string usr)
        {
            List<Users> getUser = new List<Users>();
            getUser = (from r in personal.Users where (r.UserID == usr) select r).ToList();
            List<SelectListItem> User_ID = new List<SelectListItem>();

            foreach (Users name in getUser)
            {
                User_ID.Add(new SelectListItem { Text = name.UserID, Value = name.UserName.ToString() });
            }
            return Json(new SelectList(User_ID, "Value", "Text"));

        }
        #endregion

        #region Populates Lobs according to the selected account in the Create boss-department view 
        //populate Lobs
        public JsonResult GetLOB_toAccount(int acc)
        {
            List<LOB> getLob = new List<LOB>();
            getLob = (from r in personal.LOB where (r.AccountID == acc) select r).ToList();
            List<SelectListItem> Lobs = new List<SelectListItem>();

            foreach (LOB lob in getLob)
            {
                Lobs.Add(new SelectListItem { Text = lob.LOB1, Value = lob.Indexs.ToString() });
            }
            return Json(new SelectList(Lobs, "Value", "Text"));
        }
        #endregion


        //POST: create boss-department
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CreateBoss_Dep(Boss_Dep boss_Dep)
        {
            #region Insert new record for admins only in Boss_Deapartment table in HRLoan database 

            if (ModelState.IsValid)
            {
                var Chk_UsrAccess = personal.Boss_Department.Where(x => x.BossLogin == boss_Dep.BossLogin).Any(x => x.LOBIndexs == boss_Dep.LOBIndexs);
                if (!Chk_UsrAccess)
                {
                    Boss_Department boss_Department = new Boss_Department();
                    boss_Department.BossLogin = boss_Dep.BossLogin;
                    boss_Department.LOBIndexs = boss_Dep.LOBIndexs;
                    boss_Department.IsActive = true;
                    boss_Department.ToMail = boss_Dep.To_mail;
                    boss_Department.InsertedOn = DateTime.Now;
                    boss_Department.UpdatedBy = EmployeeLogin;
                    personal.Boss_Department.Add(boss_Department);
                    personal.SaveChanges();
                    TempData["success"] = "Data saved successfully !";
                }
                else
                {
                    TempData["warning"] = "Data already exists in Boss_Department table !";
                }

            }
            else
            {
                TempData["error"] = "something went wrong :( !";
            }

            return RedirectToAction("CreateBoss_Dep");

            #endregion

        }

    }
}

1 Ответ

1 голос
/ 22 марта 2020

Поздравляем с обнаружением повторяющейся природы вашего кода. Это хорошее начало.

С другой стороны, у вас есть длинный путь к go, в этом вам нужно многому научиться.

После изучения вашего Структура кода выглядит следующим образом:

(1) Controller Class
-- (2) HTTP GET METHOD / ACTION 
-- (3) HTTP POST METHOD / ACTION
-- -- (4) If the model state is valid
-- -- -- (5) If the object does not already exist in the database
-- -- -- -- (6) Do the thing. In your case, create a record in the database and save it.
-- -- -- -- (7) While doing it, if there's an error, write it to TempData.
-- -- -- (8) Else if the object already exists in the database
-- -- -- -- (9) Write an error to the temp data
-- -- -- (10) End of check if the object exists in the database
-- -- (11) Else if the model state is not valid
-- -- -- (12) Write an error to TempData
-- -- (13) End of check if model state is valid or not
-- -- (14) If while doing the whole method thing, there's an error, write it to TempData
-- (15) End of method.

К счастью, это не новая проблема, или даже сложная для взлома. В основном это мясо и картошка всех простых приложений CRUD.

Проблема в том, что вы кричите громко и ясно, и у вас есть подозрение, что что-то не так. Вот проблема.

Все перепутано. На сложном языке вы смешиваете проблемы .

Итак, вам необходимо выделить ваши проблемы .

Это основа c принцип проектирования, а не конкретный c шаблон проектирования.

Разделение проблем

У вас есть код, который находится рядом с пользовательским интерфейсом, то есть действия вашего контроллера, ваш бизнес-объекты или модели, то есть такие классы, как пользователь, учетная запись и т. д. c. ваши служебные классы, такие как методы, которые преобразуют вещи в JSON и обратно, все в одном месте.

Кроме того, вы создали даже свои служебные методы, которые выполняют JSON и обратное преобразование из ваших бизнес-объектов. в методы publi c, что делает их вызываемыми как действия на вашем контроллере.

Все эти ошибки нарушают принципы хорошего дизайна.

Вы должны выделить их, чтобы ваш код читается как две или три строки, например:

public void PostAction(ModelObject model)
{
  if (!ModelState.IsValid)
  {
    // Some error handling strategy common to the whole
    // application that sits well with the kind of interface
    // this application has. Are you making a website or is this
    // a web API?
  }

  // You're here because the model state is valid

  // Get the repository object somehow:
  // (a) Either through dependency injection in the controller's constructor, and
  //     when you get the dependency, get it in the lowest / basest possible interface
  //     so that it is polymorphic.
  // (b) Or as a service location strategy, which means new it up here

  repositoryObject.doTheThing();
}

public class MyCentralErrorHandler : HandleErrorAttribute
{
  ...
}

При их разделении я заметил, что применил несколько шаблонов:

  1. Внедрение зависимостей
  2. Расположение службы
  3. Репозиторий

Я также применил принцип SOLID сегрегации интерфейса . То есть я получил свою зависимость, используя полиморфный c тип времени компиляции, например:

public class MyController : Controller
{
  public MyController(IRepository repositoryObject) : base()
  {
  }
}

Итак, чтобы ответить на другой аспект вашего вопроса о том, какой шаблон проектирования применить, я бы сказал, вы все еще попадаете в ту же ловушку, в которую попадают все новички. На этом этапе вам не нужно изучать шаблон проектирования. Но вам нужно больше кодировать.

Код много для практики, пока ваша собственная интуиция не разовьется до такой стадии, когда, как вы заметили, в вашем коде было что-то грязное, ваша собственная интуиция ясно и недвусмысленно говорит вам границы того, что нужно go, где, и вы начинаете работать над своей интуицией и в конце следования его инструкциям, вы понимаете: «Эй, то, что я сделал только сейчас, это называется такой-то шаблон дизайна. Альт! Я никогда не делал это сознательно. "

Итак, в двух словах, изучите их все. Узнайте все шаблоны дизайна на данный момент. Изучите их полностью и дайте ему несколько лет, чтобы катиться в вашей голове. А затем выбросьте их из головы, когда вы пишете код. Вы не должны быть супер внушительными шаблонами дизайна в своем коде. Они просто должны выйти из вас, как это делает р oop. И поверь мне, это случится. Все, что вам нужно, это просто еще несколько лет практики.

Между тем, пишите много кода. Много кода.

Еще один ответ на ваш вопрос, как я уже говорил выше, заключается в том, что вам необходимо применить следующие вещи:

  1. Принцип построения разделения проблемы;
  2. Шаблон хранилища, который сам по себе является проявлением принципа разделения интересов;
  3. Расположение службы
  4. Внедрение зависимостей
  5. Принцип SOLID программирования для интерфейса, а не для конкретной реализации
  6. Правильная стратегия обработки ошибок / исключений. Это много размышлений, которые должны быть здесь. Вам нужно задать себе много вопросов о том, какой интерфейс имеет ваше приложение и что вы собираетесь делать на каждом этапе. Это не то, что я могу написать здесь и покончить. Вам нужен наставник или много лет практики.

Еще одна вещь, на которую я должен обратить ваше внимание, - это то, что шаблоны проектирования накладываются друг на друга. Итак, есть несколько более очевидных шаблонов проектирования, которые на самом деле также go по более чем одному имени, которые уже применяются в решении, которое я выделил выше. Они в основном разные имена для одного и того же. Итак, это туманные идеи, которые выделяются в зависимости от их функции и даже контекста.

Например, просто принцип программирования для интерфейса также можно назвать сегрегация интерфейса хотя термин сегрегация интерфейса имеет другое, более широкое значение в контексте проектирования системы. Также можно заметить, что при игре полиморфизм . И я уверен, что есть другое имя шаблона, которое можно отнести к тому же здравому смыслу, очевидному решению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...