我正在编写一个将数据插入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) 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应用程序的基本要素。
问题是大声喊叫,你暗示着出了点问题。这是问题所在。
所有人都混了。用复杂的语言,您就是混合问题。
因此,您需要分离出您的担忧。
这是基本设计原则,而不是特定的设计模式。
关注点分离
[您拥有靠近UI的代码,即您的控制器操作,您的业务或模型对象,即诸如User,Account等的类。您的实用程序类(例如将东西转换为JSON的方法)地点。
您需要将它们分开,以便您的代码读起来像两三行,如下所示:
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
{
...
}
分离它们时,我注意到我应用了一些模式:
我还应用了接口隔离的SOLID原理。也就是说,我使用多态编译时类型来获得依赖,如下所示:
public class MyController : Controller
{
public MyController(IRepository repositoryObject) : base()
{
}
}
因此,要回答有关应用哪种设计模式的问题的另一个方面,我想您仍然陷入所有新秀落入的陷阱。它没有应用您在此阶段需要学习的设计模式。但是您需要编写更多代码。
代码很多进行练习,直到您的直觉发展到一个阶段,就像您发现代码有些混乱一样,您的直觉清楚明确地告诉您需要去哪里的界限,然后您开始按自己的直觉进行工作,并在遵循其指示后意识到:“嘿,我刚才所做的就是这样的设计模式。Viola!我从来没有自觉地做过。”
因此,简而言之,请全部研究它们。现在学习所有设计模式。彻底学习它们,并花几年时间动脑筋。然后在编写代码时将它们全部抛在脑后。您不应该在代码上叠加设计模式。他们只是像大便一样从你身上冒出来。相信我,它会发生的。您所需要的只是多年的实践。
同时,编写大量代码。大量的代码。
正如我上面已经说过的,对您的问题的另一种实际回答是,您需要应用三件事:
1)关注点分离的设计原则;2)存储库模式,它本身就是关注点分离原则的体现;和4)服务地点5)依赖注入6)SOLID原则,即编程为接口而不是具体实现7)正确的错误/异常处理策略。这里有很多想法。您需要问自己很多问题,这些问题涉及您的应用程序具有什么样的接口以及您打算在每个阶段做什么。这不是我可以在此处编写并完成的事情。您需要一位导师或多年的实践经验。
我必须引起您注意的另一件事是设计模式重叠。因此,在上面我强调的解决方案中已经应用了一些明显的设计模式,实际上它们实际上也使用了不止一个名称。对于同一件事,它们基本上是不同的名称。因此,这些模糊的想法是根据其功能甚至上下文来描述的。
尽管术语“接口隔离”在系统设计的上下文中具有另一个更广泛的含义,但例如,仅<>也可以称为接口隔离。在游戏中也可以注意到同一件事是polymorphism。而且我确信还有另一个模式名称可以归因于相同的常识性,显而易见的解决方案。