让我们假设我们有一个类如下所示:
public class Entity
{
public IList<string> SomeListOfValues { get; set; }
// Other code
}
Run Code Online (Sandbox Code Playgroud)
现在,假设我们想要使用EF Core Code First来保持这一点,并且我们正在使用像SQL Server这样的RDMBS.
一种可能的方法显然是创建一个Wraper包装字符串的包装类:
public class Wraper
{
public int Id { get; set; }
public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并重构类,以便它现在依赖于Wraper对象列表.在这种情况下,EF会生成一个表Entity,一个表,Wraper并建立一个"一对多"关系:对于每个实体,都有一堆包装器.
虽然这有效,但我不太喜欢这种方法,因为我们正在改变一个非常简单的模型,因为持久性问题.实际上,只考虑领域模型和代码,没有持久性,Wraper类在那里是毫无意义的.
有没有其他方法使用EF Core Code First将一个带有字符串列表的实体持久保存到RDBMS而不是创建一个包装类?当然,最后必须完成同样的事情:必须创建另一个表来保存字符串,并且必须建立"一对多"关系.我只想用EF Core做这个,而不需要在域模型中编写包装类.
假设我们有一些我们想要公开其资源的RESTful API.最终用户将通过客户端应用程序(如移动应用程序和在Web浏览器上运行的基于Javascript的客户端)使用此API.
使用OAuth 2.0,这个RESTful API将位于资源服务器上,我们将有一个授权服务器,客户端应用程序在其上注册.然后,用户将在授权服务器上注册,并且能够授予这些应用程序代表他们访问资源的权限.
因此,当用户访问一个客户端应用程序时,他将被重定向到授权服务器并被提示授予所述客户端应用程序的权限.之后,发出访问令牌,客户端能够向资源服务器发出请求.
所有这些对我来说都很清楚.只有一个缺失的部分:每个资源的保护可能取决于用户.更确切地说,它可能是依赖于声明的.我的意思是我们可以有以下情况:
只有声明为"ExampleClaim"且值为123的用户才能访问资源http://resourceserver.com/api/first-resource.
只有声明为"AnotherClaim"且值为123的用户才能访问资源http://resourceserver.com/api/second-resource.
任何用户都应该可以访问资源http://resourceserver.com/api/third-resource.
当我第一次听说OAuth正在处理ASP.NET WebAPI时,我通过以下方式解决了这个问题:当请求与Authorization: Bearer [token]头一起发送时,在服务器端设置了线程主体,我认为这意味着用户已经过身份验证使用API.所以我使用[Authorize]属性来验证用户是否可以访问资源.
在更深入地研究了OAuth之后,我看到这是对协议的一种可怕的滥用.据我所知,OAuth授权应用程序而不是用户.正如我所知,当使用Authorization标头发出请求时,访问令牌不应包含有关用户的信息,而是包含允许发出请求的应用程序的信息.
考虑到这一点,发送带有请求的Authorization标头不会识别用户,也不会说用户是否可以访问所述资源.
在这种情况下,如何执行此类授权?我的意思是,不是授权执行请求的客户端应用程序,而是根据其声明访问资源的用户的授权?我相信这是OpenID Connect及其ID令牌的用武之地,但我不确定.如何管理这个?
我正在使用Identity Server 4而我正在尝试使用内省端点,但只是通过文档我没有得到它.
文档只是给出了这个例子
POST /connect/introspect
Authorization: Basic xxxyyy
token=<token>
Run Code Online (Sandbox Code Playgroud)
现在,为什么有这个基本的身份验证,什么应该是xxxyyy?我的意思是,我的应用程序中没有基本的身份验证设置.我刚刚使用ASP.NET Core设置了Identity Server 4,如下所示ConfigureServices:
services.AddIdentityServer()
.AddTemporarySigningCredential()
.AddInMemoryApiResources(ApiResourceProvider.GetAllResources())
.AddAspNetIdentity<Usuario>();
Run Code Online (Sandbox Code Playgroud)
并在 Configure
app.UseIdentity();
app.UseIdentityServer();
Run Code Online (Sandbox Code Playgroud)
现在我只尝试了一个POST到/ connect/introspect与身体token=<token>,但它返回了404.
我相信我真的没有得到它.
我们如何在ASP.NET Core中将内省端点与Identity Server 4一起使用?
在以前的ASP.NET版本中,将Razor视图呈现为字符串是可能的,尽管不是很简单.我看起来的方法是使用假控制器,或者使用像RazorEngine这样的外部引擎.
现在,ASP.NET 5改变了很多东西,我想知道这是否比以前更简单.所以在新版本的框架中有一种直接的方式将Razor视图呈现为字符串,或者我们仍然需要使用以前版本中的方法?
阅读git的文档他们强调的一件事是git存储快照而不是增量.自从我看到Git的课程说Git存储了文件版本之间的差异后,我尝试了以下内容:我在一个空文件夹上初始化了一个git存储库,创建了一个lorem.txt包含一些lorem ipsum文本的文件,该文件暂存并提交.
然后find .git/objects -type f在命令行上使用我列出了在对象文件夹上保存的git,并且按照预期找到了一个提交对象,该对象指向指向包含我保存的lorem ispum文本的blob对象的树对象.
然后我修改了lorem ipsum文本,添加了更多内容,暂存了这个更改并提交了.再次列出文件,我现在可以看到新的提交对象,指向一个新的三个对象和一个新的blob对象.使用git cat-file -p 331cf0780688c73be429fa602f9dd99f18b36793我可以看到新blob的内容.它们正是完整lorem.txt文件的内容,旧内容加上更改.
这符合文档的预期:git存储快照,而不是增量.但是,在互联网上搜索我发现了这个问题.在接受的答案中,我们看到以下内容:
虽然这在概念层面上是真实而重要的,但在存储层面却并非如此.
Git确实使用增量来存储.
不仅如此,它比其他任何系统都更有效率.因为它不保留每个文件的历史记录,所以当它想要进行增量压缩时,需要每个blob,选择一些可能相似的blob(使用包含最接近的先前版本和其他一些版本的试探法),尝试生成增量并选择最小的增量.通过这种方式,它可以(通常取决于启发式方法)利用其他类似文件或比以前更相似的旧版本."pack window"参数允许delta压缩质量的交易性能.默认值(10)通常会得到不错的结果,但是当空间有限或加速网络传输时,git gc --aggressive使用值250,这使得它运行速度非常慢,但为历史数据提供了额外的压缩.
这说Git确实使用增量进行存储.据我所知,Git不会一直使用增量,但只有在检测到它时才有必要.这是真的?
我在文件上放了很多lorem文本,所以它的大小是2mb.我认为当对一个大文本文件做一个小改动时,Git会自动使用增量,但正如我所说的那样.
当Git使用deltas以及它是如何工作的?
我对如何在Angular 2中的模块之间共享组件存在疑问.重点是:我在应用程序中有两个模块,即"客户模块"和"供应商模块".
这些模块在其组件中都使用了AddressComponent和EmailComponent.他们也都使用接口地址和电子邮件.
现在,我目前有很多重复,因为我已经在这两个模块上复制并粘贴了这些组件和接口.这显然是完全错误的.
我需要一种方法来导入要在两个模块上使用的组件.但我不知道该怎么做.
我应该为这个共享的东西创建另一个模块并将其导入两者吗?在Angular 2中共享模块之间的组件的正确方法是什么?
我一直在阅读DDD和有限的背景,我想我的想法是错的.起初,我喜欢子域和有界上下文的想法,我理解它是这样的:有一个软件可以开发,但是同时攻击所有的东西太多了,所以我们将它分解成逻辑部分并立即开发每个部分.我们解决的另一个问题是无处不在的语言含糊不清.
这导致我将有界上下文视为基本上只是文件夹,其中我对与应用程序的某个特定部分相关的代码进行分组和绑定.这段代码我认为是由像这样的东西组成的
当然,作为域模型和基础设施在有限的上下文中正确地分开.
然而,进一步阅读,似乎每个有界的上下文都是它自己的整个应用程序.有时,似乎每个有界上下文都有自己的应用层.
这让我感到困惑,因为有时候我不想最终开发出大量的应用程序,我只想开发一个应用程序.应用程序的有界上下文划分应该构建一个应用程序,而不是要集成的应用程序.
我似乎在这个问题中@MikeSW说OP提出的两种方法都是有效的.我问的是关于第三种结构:
<bc 1>
|_ domain
|_ infrastructure
<bc 2>
|_ domain
|_ infrastructure
|_ application
|_ presentation
Run Code Online (Sandbox Code Playgroud)
至少对于所有应用程序,我觉得这更有意义.我想要一个应用程序,而不是几个带有多个演示文稿的应用程序,但我仍然希望能够打破"限制无处不在的语言"等领域并从中受益.
那么,有限的上下文是完整的应用吗?或者可以使用有限的上下文,就像我理解并感觉更有用一样?我的方法有什么问题吗?
我一直在努力了解ASP.NET 5管道中间件如何真正起作用.正如我所知,中间件只是一个Func<RequestDelegate, RequestDelegate>,它是一个指向一个方法的指针,该方法接收对下一个请求委托的引用并返回一个包装下一个请求委托的新方法.当然,我们可以使用类来表示中间件,例如:
public class MyMiddleware
{
private readonly _next;
public MyMiddleware(RequestDelegate next)
{
if (next == null)
{
throw new ArgumentNullException("next");
}
_next = next;
}
public Task Invoke(HttpContext context)
{
// New request delegate code here which can wrap the next one on the pipeline
}
}
Run Code Online (Sandbox Code Playgroud)
由于RequestDelegate是一个委托,它可以保存对接收一个方法的引用HttpContext并返回一个方法的委托,Task该Invoke方法是返回的请求委托,并且可以访问管道上的下一个委托委托.
然后,在编写中间件时,我们可以访问管道的下一个组件,但我有一个疑问.一开始我认为理想总是以下列方式工作:
HttpContext因此,当我第一次研究这个时,我认为每个中间件应该总是调用下一个.但这样做导致了这个问题所讨论的奇怪行为.
另外看一些中间件的源代码,我看到其中一些中间件遵循另一个步骤:
HttpContext的事情这是使用中间件的真正想法吗?这方面的正确方法是什么?每个中间件都会执行必须完成的请求,并始终调用下一个或者如果中间件可以处理它不再调用下一个请求的请求?
我相信中间件只有在无法处理请求时才应调用下一个.我认为这是因为如果不是,管道上的中间件之间会有耦合.因此,为了处理请求,中间件需要知道前一个做了什么以避免弄乱一切.这个结论对吗?
从VS创建一个ASP.NET 5应用程序时,该project.json文件包含以下条目:
"frameworks": {
"aspnet50": { },
"aspnetcore50": { }
}
Run Code Online (Sandbox Code Playgroud)
现在,这个框架部分是什么以及为什么有这些条目"aspnet50"和"aspnetcore50"?我知道现在有完整的.NET和Core CLR,但是这部分似乎暗示有两个不同的ASP.NET 5:一个ASP.NET 5和一个ASP.NET Core 5.只有一个框架ASP.NET 5可能运行在完整的.NET或Core CLR之上吗?如果那就是为什么我们需要这些条目?
在Angular 2中,当我们定义一个组件时,我们可以styleUrls为装饰器指定一个属性,该属性指向要应用于组件的一组样式表:
@Component({
selector: 'the-app'
templateUrl: 'templateFile.html',
styleUrls: ['componentStyles.css', 'moreComponentStyles.css']
})
export class TheAppComponent {}
Run Code Online (Sandbox Code Playgroud)
现在,如果我想用SASS写这些样式怎么办?
我知道我需要使用Gulp或Grunt将SCSS样式表转换为纯CSS.但这让我对如何正确地将Angular指向正确的样式表感到困惑.
我如何组织使用SASS和Gulp/Grunt以及Angular 2的工作流程?如何使用SASS编写Angular 2组件样式?