我有一个asp.net web api.
我想稍后在一个天蓝色的网站上拥有我的Web API.
登录用户可以在浏览器中执行此操作 /api/bankaccounts/3
让所有的细节有关bank account number 3.
但登录的用户不是所有者bank account number 3.
我如何设计我的控制器和记录后面的服务
用户只能在数据库中检索/修改自己的资源?
UPDATE
我创建了一个:
public class UserActionsAuthorizationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext != null)
{
bool canUserExecuteAction = IsResourceOwner(actionContext);
// stop propagation
}
}
private bool IsResourceOwner(HttpActionContext actionContext)
{
var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var userIdAuthenticated = Convert.ToInt32(principal.Claims.Single(c => c.Type == ClaimTypes.Sid).Value);
int targetId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
var requstScope = actionContext.ControllerContext.Request.GetDependencyScope();
var service = (ISchoolyearService)requstScope.GetService(typeof(ISchoolyearService)); …Run Code Online (Sandbox Code Playgroud) 我最近介绍了Jani Hartikainen的服务层,讨论了如何在MVC应用程序中最好地处理表单数据.之后做一些阅读我真的可以看到这种做法的好处.我的问题是:
如何构建服务类?
user_service()我的user()模型是一个合适的类名还是另一个标准?static function吗?服务类不代表数据,而是一系列动作,所以这似乎是合适的.argument,这将是一个array?考虑表单已将数据发布到控制器以保存用户数据:
<?php
class form_controller extends controller
{
public function process_submit()
{
if(user_service::update_preferences($_POST))
{
echo json_encode(array('success' => true));
}
else
{
echo json_encode(array('success' => false));
}
}
}
class user_service
{
// Accepts array()
public static function update_preferences($fields)
{
// Check for required fields
if((
isset($fields['firstname']) and
isset($fields['lastname']) and
isset($fields['email'])
) == false
{
return false;
}
// …Run Code Online (Sandbox Code Playgroud) 在企业应用程序架构模式中,Martin Fowler讨论了组织域逻辑的两种模式:域模型和服务层.域模型模式是"纯OOP"方法,其中模型(可能使用ORM从数据库中查找的那些对象)包含业务逻辑(尽管可能仅委托给另一个类中的逻辑).

服务层模式类似于域模型模式,但前面有一个薄层,包含可以执行的业务操作.在MVC中,控制器主要与服务层交互.我相信大多数精心设计的MVC Web应用程序都使用这种模式.

现在,我的问题.Martin建议域模型方法是面向对象的方法,因此更好.根据我的经验,在实践中实施非常困难(见:不可能).
以上面第一个图中给出的例子为例.有两个"实体" Contract和Product.这些使用映射器持久保存到数据库.在这个例子中,有一个RecognitionStrategy.Martin在实体本身中提出了委托此策略的方法,该策略包含实际的业务逻辑; 客户端使用contract.calculateRecognitions或执行此计算contract.recognizedRevenue(someDate).在实现类似设计时,我通常将客户端接口编写为strategy.calculateRecognitions(contract)和strategy.recognizedRevenue(contract, someDate).这使得服务层成为协调战略和合同所必需的.使用的具体策略注入服务.
从设计的角度来看,Martin的方法肯定更具吸引力,但围绕设置的工作要困难得多:
Product是一种痛苦.您需要Product通过一个使用具体服务的工厂创建s,然后在创建它时将其传递给实体.Contract委托Product可以执行查询Product.Product当我们加载a Contract但不打算调用时,在mapper(或ORM)中贪婪地加载s可能过于热心contract.calculateRecognitions().我的方法为我们提供了更细粒度的控制,因为服务具有数据库抽象层的知识,而实体则不应该知道.我确信在实践中还有更多的痛点,我在这里没有列举.
Martin的方法有哪些具体优势可能说服我使用纯数据模型模式?
design-patterns architectural-patterns service-layer anemic-domain-model
我一直在大量阅读服务层和业务层以及它们的比较方式.我已经在StackOverflow上阅读了关于这个主题的一些线程,我仍然发现自己对两者之间的差异感到困惑,如果有的话.对我而言,它似乎主要是一种命名约定,其中一个开发人员将中间层称为业务层,另一个开发人员可将其称为服务层.从我在SO和网络上看到的代码看起来他们似乎主要做同样的事情 - 即查询存储库,可能进行一些过滤和/或验证并将结果返回到表示层.那么有人可以澄清两者之间的差异吗?或者我在考试中错过了标记?
我正在与EF,MVC 3和VBNET,FYI合作
architecture model-view-controller asp.net-mvc business-logic-layer service-layer
我有一个 MVC 项目,它有两个服务:OrganizationService 和AgreementService,我的问题是某些组织属于组/父结构,在这种情况下,我需要获取属于其中任何组织的所有协议群组。
我的 OrganizationService 中已经有一个方法,可以返回结构内组织的所有 id 列表:
IEnumerable<int> GetRelatedOrganisationIds(int id)
Run Code Online (Sandbox Code Playgroud)
我可以在AgreementService中创建一个方法来接受此结果,但随后我需要将这两个服务注入我的控制器并依次调用它们,例如
GetAgreementsByOrganisationIdList(IEnumerable<int> organisationIdList)
Run Code Online (Sandbox Code Playgroud)
是否可以将OrganizationService注入到AgreementService中,以便它可以自己完成工作?例如,以下方法将在内部调用 GetRelatedOrganizationIds:
GetAgreementsByOrganisationId(int id)
Run Code Online (Sandbox Code Playgroud)
我想将其注入到AgreementService 中的另一个原因是,我不需要记住检查组织是否处于组/父关系中,也不需要在每次想要获取协议列表时查找ID。
我还考虑过创建一个 OrganizationGroupParentInformationProvider 并将其注入到AgreementService 中,我可能花了太多时间思考这个......你会怎么做?
我目前正在构建一个Web应用程序,并尝试按照良好的MVC和面向服务的体系结构进行设计.
但是,我在连接表示层(即我的控制器)和后端服务时遇到了一些障碍,同时仍然保持良好的错误/验证报告给用户.
我在这里阅读了一篇非常好的SO帖子,关于如何将验证逻辑与服务层分开,并且大部分都是有意义的.然而,有一个"缺陷",如果你可以称之为,在这个模型中,我嘻嘻哈哈:在查找验证器和服务所需的对象时,如何避免重复工作?
我认为用一个相当简单的例子解释会更容易:
假设我有一个允许用户共享代码片段的应用程序.现在,我决定添加一项新功能,允许用户将他们的GitHub帐户附加到我的网站上的帐户(即建立个人资料).出于这个例子的目的,我将简单地假设我的所有用户都是值得信赖的,并且只会尝试添加他们自己的GitHub帐户,而不是其他人的:)
按照前面提到的SO文章,我已经设置了一个基本的GitHub服务来检索GitHub用户信息.
interface IGitHubUserService {
GitHubUser FindByUserName(string username);
}
Run Code Online (Sandbox Code Playgroud)
GitHubUserService的具体实现会进行昂贵的调用以https://api.github.com/users/{0}获取用户信息.再次,按照文章的模型,我实现了以下命令将用户帐户链接到GitHub用户:
// Command for linking a GitHub account to an internal user account
public class GitHubLinkCommand {
public int UserId { get; set; }
public string GitHubUsername { get; set }
};
Run Code Online (Sandbox Code Playgroud)
我的验证者需要验证用户输入的用户名是否是有效的GitHub帐户.这是非常简单的:调用FindByUserName上GitHubUserService,并确保结果不为空:
public sealed class GitHubLinkCommandValidator : Validator<GitHubLinkCommand> {
private readonly IGitHubUserService _userService;
public GitHubLinkCommandValidator(IGitHubUserService userService) {
this._userService = userService;
}
protected override IEnumerable<ValidationResult> Validate(GitHubLinkCommand command) …Run Code Online (Sandbox Code Playgroud) 我正在使用服务层,直到现在我使用了ServiceObject(实现了ArrayAccess,Iterator,Countable),但我想知道这是不是一个好主意.
你会怎么做:
ArticleService::createArticle($articleData, $userId);
Run Code Online (Sandbox Code Playgroud)
要么
ArticleService::createArticle(ServiceObject $data);
Run Code Online (Sandbox Code Playgroud)
在哪里$data:
array(
'title' => 'Lorem ipsum',
'body' => 'Dolor sid amet',
'userId' => 55,
);
Run Code Online (Sandbox Code Playgroud)
ServiceObject具有为每个方法提供通用签名的好处,但有时它看起来效率不高,并且它没有被广泛使用,它失去了它的兴趣.
任何反馈?
与我的另一个问题有点相关应该从数据访问层或接口返回原始的Hibernate注释POJO吗?,我在创建很好的分离层方面很有经验,但没有使用Hibernate或J2EE/JPA.我一直在查看文档和教程,并对如何以优雅的方式使用EntityManger感到困惑,因为它似乎负责两个事务(我想在我的服务层执行)和持久性方法(我想要的)保持在数据访问层).我应该在服务层创建它并将其注入数据访问层,还是有更好的方法?下面的伪java大致显示了我正在考虑做的事情.
编辑:我的下面的伪代码主要取自hibernate JPA教程,并针对图层分离进行了修改,并未反映出该产品是在EJB容器(Glassfish)中运行的.在您的答案中,请提供在Glassfish中运行的代码或同等代码的最佳实践和代码示例.
MyService
{
setup()
{
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "Something" ); //is the String you pass in important?
entityManager = entityManagerFactory.createEntityManager();
}
myServiceMethod()
{
entityManager.getTransaction().begin();
MyDao.setEntityManager(entityManagerFactory);
MyDao.doSomething();
MyDao.doSomethingElse();
entityManager.getTransaction().commit();
entityManager.close();
}
}
MyDao
{
doSomething()
{
entityManager.persist(...); //etc
}
}
Run Code Online (Sandbox Code Playgroud) 我做了很多研究,包括SO,我似乎无法找到明确的方向.我目前有一个ASP.NET MVC3应用程序,其中一个服务层位于存储库之上.
在我的服务层,我有以下功能:
public class MyService{
public void CreateDebitRequest(int userId, int cardId, decimal Amount, .... )
{
//perform some sort of validation on parameters, save to database
}
public void CreateCreditRequest(.....)
}
//perform some sort of validation on parameters, save to database
}
public void CreateBatchFile()
{
//construct a file using a semi-complex process which could fail
//write the file to the server, which could fail
}
public PaymentTransaction ChargePaymentCard(int paymentCardId, decimal amount)
{
//validate customer is eligible for amount, …Run Code Online (Sandbox Code Playgroud) 我想知道大多数开发人员如何使用这两个Laravel工具。
在Laravel中,您可以使用“服务”或“作业”来处理业务逻辑(让我们仅讨论不可排队的作业,仅讨论那些在同一流程中运行的作业)。
例如,一个用户想要创建一个实体,比如说一本书,您可以使用服务来处理该实体的创建或调度一个工作。
使用工作将是这样的:
class PostBook extends Job
{
...
public function handle(Book $bookEntity)
{
// Business logic here.
}
...
}
class BooksController extends Controller
{
public function store(Request $request)
{
...
dispatch(new PostBook($request->all()));
...
}
}
Run Code Online (Sandbox Code Playgroud)
使用服务,将是这样的:
class BookService
{
public function store(Request $request)
{
// Business logic here.
}
}
class BooksController extends Controller
{
public function store(Request $request)
{
...
// I could inject the service instead.
$bookService = $this->app()->make(App\Services\BookService::class);
$bookService->store($request);
... …Run Code Online (Sandbox Code Playgroud) service-layer ×10
c# ×4
asp.net-mvc ×3
php ×3
architecture ×1
hibernate ×1
jpa ×1
laravel ×1
laravel-5 ×1
repository ×1
validation ×1