首先让我把它扔出去,我知道下面的代码不是线程安全的(更正:可能).我正在努力的是找到一个实现,并且我实际上可以在测试中失败.我现在正在重构一个大型WCF项目,它需要一些(大部分)静态数据缓存并从SQL数据库中填充.它需要每天至少过期和"刷新"一次,这就是我使用MemoryCache的原因.
我知道下面的代码不应该是线程安全的,但我不能让它在繁重的负载下失败,并且使谷歌搜索显示两种方式的实现变得复杂(有和没有锁结合辩论,无论它们是否必要.
在多线程环境中具有MemoryCache知识的人可以让我明确地知道我是否需要在适当的地方锁定,以便在检索/重新填充期间不会抛出删除调用(很少被调用但是它的要求).
public class MemoryCacheService : IMemoryCacheService
{
private const string PunctuationMapCacheKey = "punctuationMaps";
private static readonly ObjectCache Cache;
private readonly IAdoNet _adoNet;
static MemoryCacheService()
{
Cache = MemoryCache.Default;
}
public MemoryCacheService(IAdoNet adoNet)
{
_adoNet = adoNet;
}
public void ClearPunctuationMaps()
{
Cache.Remove(PunctuationMapCacheKey);
}
public IEnumerable GetPunctuationMaps()
{
if (Cache.Contains(PunctuationMapCacheKey))
{
return (IEnumerable) Cache.Get(PunctuationMapCacheKey);
}
var punctuationMaps = GetPunctuationMappings();
if (punctuationMaps == null)
{
throw new ApplicationException("Unable to retrieve punctuation mappings from the database.");
}
if (punctuationMaps.Cast<IPunctuationMapDto>().Any(p => p.UntaggedValue …Run Code Online (Sandbox Code Playgroud) 当我们开始我们的最新项目(大型框架)时,我们开始使用ProGet作为我们的包服务器和TeamCity进行构建(Visual Studio Team Services是SC).该框架中的一个解决方案包含近60个代码库,它们实现了从redis到外部API和常见模型的包装器的所有功能.这些库中的每一个都是一个nuget包.在项目的早期,很容易在核心库中进行更改,检查它,TeamCity将构建并推送到proget并快速更新,并且您已经关闭并运行.
虽然这变得无法管理,但团队决定在开发过程中,公共库解决方案中的nuget包不会通过其包引用彼此,而是直接引用.这当然加快了开发速度,但对消费应用程序产生了令人讨厌的副作用.虽然公共库是直接引用,但是在更新任何内部包时,微服务框架的7个主要部分(web api,多个mvc和一些工作者角色)将获得相同核心库的多个副本,而所有其他库依赖于这些库.上.
例如,有一个名为"core"的lib,它具有构建块,几乎所有内容都是在公共库中构建的.它有很多接口等等......好吧,因为所有其他的lib都直接使用它们,它们都直接在它们的输出中获得了一个核心副本,更令人担忧的是我们的teamcity服务器为我们处理版本控制,所以它们不仅仅是每个都有一个核心副本,但其版本与使用它的nuget包的版本相匹配.
虽然不是很好,但这仍然不是问题的症结所在.在消费应用程序中进行nuget更新期间,应用程序中的每个库可能会引用不同版本的核心,具体取决于更新的程序包的顺序,这些程序偶尔会导致构建错误并搜索恶意引用.
既然项目正在进入最后阶段,我想永久解决这个问题,但我不确定如何.
为了让nuget包作为nuget包相互消耗,单个更新可能需要几个小时,因为一个依赖包被更新,你重建,它会生成另一个nuget包,链中更高的包需要等等...
然而,版本控制至关重要,因为在引入重大更改时,我们希望利用nuget依赖关系来防止在需要时进行升级.
有没有其他人遇到这个并解决了它?如果nuget被任何开发团队完全接受并且生成一个相当大的项目,那么这似乎是相当普遍的.
更新:
引擎盖下发生的事情的例子.
CoreLib(接口等)Lib1(直接引用Corelib,当前版本= v1.0.17)Lib2(直接引用Corelib,当前版本= v1.0.99)
Lib1和Lib2都是nuget包.对Lib1进行了更新,其中包括对CoreLib的不间断更改.签入Lib1时,TeamCity启动构建并创建新的nuget包,v1.0.18).
当Lib1的软件包在消费项目中更新时,Lib1的CoreLib副本(也是v1.0.18,因为AssemblyVersion由TeamCity管理)的版本低于Lib2的版本(v1.0.99),即使它是落后的版本.
最终目标是让所有这些相互依赖的软件包自行重建,更新和重新打包,但如何自动执行此操作实际上是在逃避我.
我正在开发一个新的asp.net web api restful服务,并花了一些时间在这个主题上的一些Pluralsight课程.其中一个更好的潜水深入设计和超媒体(HATEOAS)的实现.
我跟踪了视频中的实现,因为它非常直接并且是mvc/web api的新手,看到它端到端工作真的很有帮助.
但是,当我开始深入研究我的实现时,使用UrlHelper()来计算返回的链接开始分崩离析.
在下面的代码中,我有一个简单的Get(),它返回一个特定资源的集合,然后是一个Get(int id),它允许返回一个单独的资源.
所有结果都通过一个ModelFactory,它将我的POCO转换为返回结果,然后再返回post,patch和puts.
我试图通过允许ModelFactory处理链接创建的所有智能来以更复杂的方式执行此操作,因为它是使用Request对象构造的.
现在我知道我可以通过简单地处理我的方法中的链接生成/包含来解决所有这些问题,也许这就是答案,但我很好奇其他人如何处理它.
我的目标:
1)在结果集(即"Get()"返回的结果集合)中,根据需要包括总项目数,总页数,下一页和上一页.我已经实现了一个自定义的json转换器来删除地面上的空链接.例如,当您在第一页时,我不会打印出"prevPage".今天有效.
2)在单个结果中(即"Get(id)"返回的结果),包括指向self的链接,包括rel,链接所代表的方法以及是否模板化.今天有效.
什么是坏的:
正如您将在下面的输出中看到的,有两件事是"错误的".当您查看新单个项目的"POST"链接时,URL是正确的.这是因为我正在剥离URI的最后一部分(删除资源ID).但是,返回结果集时,"POST"的URI现在不正确.这是因为路由不包括单个资源ID,因为调用了"Get()",而不是"Get(id)".
同样,可以改变实现以产生不同的链接,具体取决于被击中的方法,将它们拉出工厂并进入控制器但是我想相信我只是遗漏了一些明显的东西.
这个新手路由和Web API的指针?
控制器Get()
[HttpGet]
public IHttpActionResult Get(int pageSize = 50, int page = 0)
{
if (pageSize == 0)
{
pageSize = 50;
}
var links = new List<LinkModel>();
var baseQuery = _deliverableService.Query().Select();
var totalCount = baseQuery.Count();
var totalPages = Math.Ceiling((double) totalCount / pageSize);
var helper = new UrlHelper(Request);
if (page > 0)
{
links.Add(TheModelFactory.CreateLink(helper.Link("Deliverables",
new
{
pageSize,
page = page - …Run Code Online (Sandbox Code Playgroud)