This is strange, and I do not understand what is happening here. I have a web api project that, in one controller, calling a specific method ultimately calls a function in a service that looks like this:
public MyClassBase GetThing(Guid id)
{
if (cache.ContainsKey(id))
{
return cache[id];
}
else
{
var type = typeof(MyClassBase).Assembly.GetTypes().FirstOrDefault
(
t => t.IsClass &&
t.Namespace == typeof(MyClassBase).Namespace + ".Foo" &&
t.IsSubclassOf(typeof(MyClassBase)) &&
(t.GetCustomAttribute<MyIdAttribute>()).GUID == id
);
if (type != null)
{
System.Diagnostics.Debug.WriteLine(string.Format("Cache null: {0}",cache == null));
var param = (MyClassBase)Activator.CreateInstance(type, userService);
cache[id] = param;
return param;
}
return null;
}
}
cache - just a dictionary:
protected Dictionary<Guid, MyClassBase> cache { get; set; }
This is created in the constructor for this class:
cache = new Dictionary<Guid, MyClassBase>();
This works fine in 99.9% of cases, but sometimes when you first launch the application, the first request will be thrown NullReferenceException- and the strange part, it claims that this line is the source:
cache[id] = param;
But the fact is that if it cacheis null (which cannot be, it was set in the constructor, it is private, and this is the only method that even affects it), then it should
if (cache.ContainsKey(id))
id null, api, , linq, GUID, null, . param NULL, , .
, - , , .
, () ( JSON, web api json, , , ):
{
"message": "An error has occurred.",
"exceptionMessage": "Object reference not set to an instance of an object.",
"exceptionType": "System.NullReferenceException",
"stackTrace": " at System.Collections.Generic.Dictionary`2.Insert(TKey key,
TValue value, Boolean add)\r\n at
System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)\r\n
at MyNameSpace.Services.MyFinderService.GetThing(Guid id) in
c:\\...\\MyFinderService.cs:line 85\r\n
at MyNameSpace.Controllers.MyController.GetMyParameters(Guid id) in
c:\\...\\Controllers\\MyController.cs:line 28\r\n at
lambda_method(Closure , Object , Object[] )\r\n at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.
<GetExecutor>b__c(Object instance, Object[] methodParameters)\r\n at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance,
Object[] arguments)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.
<>c__DisplayClass5.<ExecuteAsync>b__4()\r\n at
System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken
cancellationToken)"
}
line 85 - , .
Heisenbug, , html ( , , ):
$.ajax({
url: "@Url.Content("~/api/MyController/GetMyParameters")",
data: { id: '124c5a71-65b7-4abd-97c0-f5a7cf1c4150' },
type: "GET"
}).done(function () { console.log("done"); }).fail(function () { console.log("failed") });
$.ajax({
url: "@Url.Content("~/api/MyController/GetMyParameters")",
data: { id: '7cc9d80c-e7c7-4205-9b0d-4e6cb8adbb57' },
type: "GET"
}).done(function () { console.log("done"); }).fail(function () { console.log("failed") });
$.ajax({
url: "@Url.Content("~/api/MyController/GetMyParameters")",
data: { id: '1ea79444-5fae-429c-aabd-2075d95a1032' },
type: "GET"
}).done(function () { console.log("done"); }).fail(function () { console.log("failed") });
$.ajax({
url: "@Url.Content("~/api/MyController/GetMyParameters")",
data: { id: 'cede07f3-4180-44fe-843b-f0132e3ccebe' },
type: "GET"
}).done(function() { console.log("done"); }).fail(function() { console.log("failed")});
, , , , , cache, id param Visual Studio , ! cache a Count of 1, , , Ninject, - Ninject.
, NinjectWebCommon, :
kernel.Bind<Services.IMyFinderService>().To<Services.MyFinderService>().InSingletonScope();
. , 100% , Ninject, , .