我正在开发一个项目(带有 jQuery 的 asp.net mvc-5),其中整个验证在前端进行,我们正在使用 $.ajax 调用执行 API,现在因为没有 API 级别的验证,甚至没有在 sql server 的存储过程中,用户很容易访问带有错误值的 API,因此我们决定在我们的应用程序中添加一个逻辑层。
所以在那之前我们的结构如下所示
jQuery -> Api layer -> Db layer
现在我想在
Api layer
和Db layer
之间添加一个层,这将被称为Logic layer
.
新结构如下所示
jQuery -> Api layer -> Logic layer -> Db layer
注:
所以我们有 4 个类库 1 个 api 和 1 个前端。接口在类文件中继承。类库如下
db.Interface(类库项目)
db.Class(类库项目)
Logic.Interface(类库项目)
Logic.Class(类库项目)
我们已经为 db 层添加了依赖项,其代码如下所示,
global.asax.cs 中的代码集
//Helps to find all the classes of Dblayer
string dbName = ConfigurationManager.AppSettings["DB"];
string dbDAL = Path.Combine(Server.MapPath("./DAL"), "DocPro.DMS.BusinessLayer." + dbName + ".dll");
AssemblyName an = AssemblyName.GetAssemblyName(dbDAL);
Assembly assembly = Assembly.Load(an);
Type[] assemblyTypes = assembly.GetTypes();
DALFinder.Initialize(assemblyTypes);
api 项目中名为 DalFinder 的类文件
public static class DALFinder
{
private static List<Type> TypeList { get; set; } = new List<Type>();
public static void Initialize(Type[] typelist)
{
TypeList.Clear();
TypeList = typelist.ToList<Type>();
}
public static object GetInstance(Type plugin)
{
foreach (Type type in TypeList)
{
if (type.IsInterface || type.IsAbstract)
{
continue;
}
else
{
if (type.GetInterface(plugin.FullName) != null)
{
return Activator.CreateInstance(type, new object[] { Program.GetConnectionString() });
}
}
}
return null;
}
}
在执行特定功能时,我需要在我的 Api 层中执行以下操作
BusinessLayer.IAdmin.IFolderRole a = (BusinessLayer.IAdmin.IFolderRole)DALFinder.GetInstance(typeof(BusinessLayer.IAdmin.IFolderRole));
response = a.SaveFolderRole(item);
现在对于我当前的场景,我想从我的逻辑层调用 db 层,但由于它是一个类库文件,我无法理解我应该做什么,现在我做了如下的事情
public class DocTemplateController : ApiController
{
private LogicLayer.IAdmin.IDocTemplate _LogicLayer;
private BusinessLayer.IAdmin.IDocTemplate _Businesslayer;
public DocTemplateController()
{
_LogicLayer = (LogicLayer.IAdmin.IDocTemplate)BusinessLayerFinder.GetInstance(typeof(LogicLayer.IAdmin.IDocTemplate));
_Businesslayer = (BusinessLayer.IAdmin.IDocTemplate)DALFinder.GetInstance(typeof(BusinessLayer.IAdmin.IDocTemplate));
}
[HttpPost]
[Route("api/Admin/DocTemplate/GetDocTemplates")]
[Authorize]
[Filters.AuthorizeLoginApi()]
public async Task<GetTemplatesList> GetDocTemplates(DocTemplate request)
{
var response = new GetTemplatesList() { LogicLayerValidation = false };
try
{
response = _LogicLayer.GetDocTemplates(request);
if (response.LogicLayerValidation != false)
response.GetTemplates = await _Businesslayer.GetDocTemplates(request.TemplateName, request.AccountId);
}
catch (Exception ex)
{
Utils.Logger.Instance.LogException(ex);
response.LogicLayerValidation = false;
response.LogicLayerMessage = ex.Message;
}
return response;
}
}
据我所知(我可能是错的)这是一种糟糕的编码方式,我想遵循
的结构jQuery -> API layer -> Logic layer -> Db layer
我该怎么做?
我想我需要编辑这个问题并提供更多细节。全部 答案很好,对很多人都非常有帮助,但不幸的是我没能得到我想要的。
这就是我的控制器的样子:
[RateLimitApi]
public class UserController : ApiController
{
private readonly LogicLayer.IAdmin.IUsers _LogicLayer;//Logic layer
private readonly LogicLayer.IGlobalValidation _CommonLogicLayer; //common logic layer
private readonly BusinessLayer.IAdmin.IUsers _Businesslayer;// business layer
private readonly BusinessLayer.IAccess.IUser _IAccessBusinesslayer;//business layer which is being used in another api
private BusinessEntities.Response.LogicLayerValidationResult _Llv; //entity for logiclayer
private SPResponse _Sp; //response entity for add/edit
private readonly ErrorLogger _Er; error log class
private readonly BusinessEntities.Response.Admin.GetUsersList _UserList; //user list
private readonly BusinessEntities.Response.Admin.GetUsersSingle _UserSingle; //single user
public UserController()
{
_LogicLayer = (LogicLayer.IAdmin.IUsers)BusinessLayerFinder.GetInstance(typeof(LogicLayer.IAdmin.IUsers));
_Businesslayer = (BusinessLayer.IAdmin.IUsers)DALFinder.GetInstance(typeof(BusinessLayer.IAdmin.IUsers));
_IAccessBusinesslayer = (BusinessLayer.IAccess.IUser)DALFinder.GetInstance(typeof(BusinessLayer.IAccess.IUser));
_CommonLogicLayer = (LogicLayer.IGlobalValidation)BusinessLayerFinder.GetInstance(typeof(LogicLayer.IGlobalValidation));
_Llv = new BusinessEntities.Response.LogicLayerValidationResult() { LogicLayerValidation = false };
_Sp = new SPResponse();
_Er = new ErrorLogger();
_UserList = new BusinessEntities.Response.Admin.GetUsersList();
_UserSingle = new BusinessEntities.Response.Admin.GetUsersSingle();
}
// GET: Admin/Users
[HttpPost]
[Authorize]
[ActionName("GetList")]
[Filters.AuthorizeLoginApi()]
public async Task<BusinessEntities.Response.Admin.GetUsersList> GetList(DocPro.DMS.BusinessEntities.Request.Admin.UsersRequest request)
{
try
{
// had to call logic layer and then call the business layer like below
_Llv = _LogicLayer.GetList(request);
if (_Llv.LogicLayerValidation)
{
_UserList.GetUsers = await _Businesslayer.GetList(request.LoginText, request.Name, request.Email, request.UserTypeId, request.IsActive, Convert.ToInt32(request.LoggedInUserId));
}
}
catch (Exception ex)
{
_Llv = _Er.LogExceptionWithLogicLayerValidations(ex, _Llv);
}
_UserList.LogicLayerValidation = _Llv;
return _UserList;
}
}
我该怎么做?
是一个非常普遍的问题(在这个社区中不受欢迎)。
我没有看到结构有任何问题:
jQuery -> Api 层 -> 逻辑层 -> Db 层
很常见的结构:frontend -> api-> business (logic) layer -> db
如果它是一个新项目,我可能会建议使用 .net core 并使用 Microsoft 依赖注入或者使用 Autofac,因为主题很复杂。如果你真的想做,那么你也可以在github上浏览他们的(ms或autofuc)代码来熟悉主题。
您应该在逻辑层项目中添加对数据库层项目的引用。然后你可以使用依赖注入在你的逻辑层类中注入数据库层类。
然后你可以在完成验证后从逻辑层调用数据库层。
为什么要重新发明轮子?
您要求的内容已在 AspNet Boilerplate
中实现
更多关于这个here