gpt4 book ai didi

c# - IMemoryCache 未在类库中实例化

转载 作者:太空宇宙 更新时间:2023-11-03 14:52:00 25 4
gpt4 key购买 nike

我对 ASP.Net Core、C#、OOP、Javascript ……基本上是我目前使用的所有内容的新手。过去几个月我一直在阅读和学习以开始一个新的开发项目。总而言之,我正在稳步前进,但我遇到了 IMemoryCache 的问题,我无法真正理解(或者是 DI?)。

我正在使用 ASP.Net Core 2.0 和 VS2017。我有一个包含 2 个项目的解决方案,我的主要 ASP.Net Core MVC Web 应用程序和一个 .Net Core 2.0 类库。

在类库中,我添加了一个我想在其中使用缓存的类,因此我将 IMemoryCache 添加到构造函数中。为了实例化类,我有另一个调用函数 GetModelGuidAsync 的构造函数。

public class MdsEntityCRUD
{
#region ClassConstruct

private readonly IMemoryCache _cache;
public MdsEntityCRUD(IMemoryCache cache)
{
_cache = cache;
}

public MdsEntityCRUD(ServiceClient client, string modelName, string entityName, string versionFlag)
{
this.client = client;
this.ModelId = Task.Run(async () => await GetModelGuidAsync(modelName)).Result;
this.EntityName = entityName;
mdsWS.Version ver = Task.Run(async () => await GetVersionByPolicyAsync(client, VersionPolicy.Flag, versionFlag, this.ModelId)).Result;
this.VersionId = ver.Identifier.Id;
}

public async Task<Guid> GetModelGuidAsync(string modelName)
{
Dictionary<string, Guid> modelNames;

if (!_cache.TryGetValue("ModelNames", out modelNames) || !modelNames.ContainsKey(modelName))
{
modelNames = await GetModelNamesAsync();
_cache.Set("ModelNames", modelNames, new MemoryCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60) }); // CFG
}

return modelNames[modelName];
}

我已将 services.AddMemoryCache(); 添加到我的 MVC 项目启动中的 ConfigureServices 中。我正在使用第二个构造函数从我的 MVC 项目中的 Controller 调用该类。在运行时,我在 if (!_cache.TryGetValue-statement 中收到错误。这些是异常帮助程序和异常窗口中显示的详细信息:

System.AggregateException HResult=0x80131500 Message=One or more errors occurred. (Object reference not set to an instance of an object.) Source=System.Private.CoreLib StackTrace: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at mdXmdsWS.MdsEntityCRUD..ctor(ServiceClient client, String modelName, String entityName) in C:\Users..\MdsEntityCRUD.cs:line 59 at MDS_MVC_Proto2.Controllers.DataExplorerController.EntityDataSource(DataManagerRequest dmr) in C:\Users..\Controllers\DataExplorerController.cs:line 165
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__12.MoveNext()

Inner Exception 1: NullReferenceException: Object reference not set to an instance of an object.

and from ($exception).InnerException

  • InnerException {System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Extensions.Caching.Memory.CacheExtensions.TryGetValue[TItem](IMemoryCache cache, Object key, TItem& value) at mdXmdsWS.MdsEntityCRUD.d__18.MoveNext() in C:\Users..\MdsEntityCRUD.cs:line 84 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at mdXmdsWS.MdsEntityCRUD.<>c__DisplayClass16_0.<<-ctor>b__0>d.MoveNext() in C:\Users..\MdsEntityCRUD.cs:line 59} System.Exception {System.NullReferenceException}

我不知道为什么会收到错误消息:是因为缓存在Class库中,而不是在MVC项目中吗?是因为我试图在从构造函数执行的函数中使用缓存吗?我是否缺少某些配置?

渴望了解我哪里出错了......

最佳答案

正如评论中指出的那样,依赖注入(inject) (DI)/控制反转 (IoC) 并不是魔法。从根本上说,依赖注入(inject)只是意味着:“将对象 A 的实例传递给构造函数/方法,而不是 new - 在构造函数/方法中对其进行处理”。

var service = new MyService(new MyDependency());

这已经是依赖注入(inject)了,你注入(inject)一个依赖到MyService,如果它接受一个基类/接口(interface),它的实现可以在不改变MyService的情况下改变。这种方法通常被称为“穷人 DI”,没有任何外部工具或库。

然后是 DI/IoC 框架,它使这更容易,所以你不必自己 new 实例并将其注入(inject)服务以及为你管理对象的生存时间(每个类都应该获得相同的实例吗?(单例生命周期)还是每次都有一个新实例?( transient 生命周期)特定的一组类是否应该获得一个实例,而其他组是否应该获得另一个实例?(作用域生命周期))。

无论有没有框架使用DI/IoC,都要一直往下用。没有魔法参与。 IoC 框架与上述相同,new-ing 类及其依赖项并传递给它们的构造函数。

在 ASP.NET Core 的情况下, Controller 通过内置的 DI/IoC 框架解析,因此您可以注入(inject)任何已注册的类(在 Startup 的 ConfigureServices 方法中)。

在您的情况下,您显然是 new - 使用第二个构造函数创建类,因此永远不会调用第一个构造函数,也永远不会设置 _cache 成员变量。当您尝试访问它时,您会遇到可怕的 NullReferenceException 异常。您必须将依赖项添加到主构造函数。

如果在你的情况下你喜欢new一个类,你必须自己传递依赖关系。在您的情况下,您需要将 IMemoryCache 注入(inject)您的 Controller ,然后将其传递给您的 new-ed 类。

IMemoryCache缓存

public class MyController : Controller 
{
private readonly MdsEntityCRUD mdsCrud;

public MyController(IMemoryCache memoryCache)
{
ServiceClient client = ...;
mdsCrud = new MdsEntityCRUD(memoryCache, client, "modelname", "entityName", "v1");
}
}

通过这种方式,您可以从 Controller 获取正确的 IMemoryCache 实例,您可以将其传递给服务。

还有其他更优雅的抽象方法(使用 ConfigureServices 中的工厂类或工厂方法)来执行此操作,但这超出了问题的范围。

关于c# - IMemoryCache 未在类库中实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51404012/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com