This is a confusing problem for me. I'm passing a Guid into a method from a different DLL, and that Guid, as an argument, seems to lose scope - the Guid retains random values before the first two hyphens, but anything after is strangely zeroed out. The DLL represents code that is also running as a Windows Service, but I stopped the Windows Service and still notice the same behavior).
Guid before method call (which is the correct Guid): e808b3fa-ab7c-48fc-8224-535e41393532
Guid after method call: b287a7d0-00d5-0000-0000-000000000000 (I've run the debugger several times, and the Guid always changes, but seems to always be zeroed out after the second hyphen)
I think I've explained the issue already, but in case code makes things more clear, here's a somewhat minimal code example:
// Service.Business.Service.cs
public static class Service
{
internal static readonly CalendarService.ClientProxy.Calendar TradingCalendar;
static Service()
{
TradingCalendar = CalendarService.ClientProxy.Service.Calendars.GetCalendarByUidOrThrow(ServiceSettings.Instance.TradingCalendarUid); // value of ServiceSettings.Instance.TradingCalendarUid is e808b3fa-ab7c-48fc-8224-535e41393532 when debugger paused on this line
}
public static void Initialize()
{
}
}
// Service.Business.ServiceSettings.cs
public class ServiceSettings : SettingsBase
{
private static readonly ServiceSettings _Instance = new ServiceSettings();
public static ServiceSettings Instance { get { return _Instance; } }
public Guid TradingCalendarUid { get; private set; }
}
// Calendar.CalendarService.ClientProxy.Calendars.cs
public class Calendars : ClientWrapperCacheBase<CalendarDto, Calendar, Guid>, IEnumerable<Calendar>, IEnumerable
{
public Calendar GetCalendarByUidOrThrow(Guid calendarUid)
{
Calendar calendarByUid = GetCalendarByUid(calendarUid); // value of calendarUid is b287a7d0-00d5-0000-0000-000000000000 when debugger paused on this line
}
}
And my functional test I'm using to debug this issue:
[TestMethod]
public void ServiceConstructor()
{
Service.Business.Service.Initialize();
}
It should be noted that others developed this codebase, and I'm somewhat new to it. I don't think this issue was happening before my code changes (as this is a production codebase), wherein I'm in the middle of upgrading from on-premise ServiceBus to Azure Cloud hosted ServiceBus across all the windows services.
EDIT (answer to "Where is TradingCalendarUid set?"):
(TradingCalendarUid corresponds to a column from a row in a (MS) SQL Server table... I assumed this information was trivial, but providing this code here in case it sheds light on things.)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
// namespace name omitted
public abstract class SettingsBase
{
private readonly bool ThrowOnMissingSettings;
public SettingsBase(bool throwOnMissingSettings = false)
{
ThrowOnMissingSettings = throwOnMissingSettings;
}
protected abstract List<SettingData> OnLoad();
protected void Load()
{
Type type = GetType();
List<SettingData> list = OnLoad();
if (list == null)
{
list = new List<SettingData>();
}
if (ThrowOnMissingSettings)
{
List<string> list2 = (from property in type.GetProperties()
join setting in list on property.Name equals setting.Name into setting_join
from _setting in setting_join.DefaultIfEmpty()
where _setting == null
select property.Name).ToList();
if (list2.Count > 0)
{
throw new Exception("Missing configuration: " + string.Join(", ", list2));
}
}
foreach (SettingData item in list)
{
PropertyInfo property2 = type.GetProperty(item.Name);
if (property2 == null)
{
throw new Exception($"Invalid Setting. Name: {item.Name}");
}
TypeConverter converter = TypeDescriptor.GetConverter(property2.PropertyType);
if (converter == null)
{
throw new Exception($"Converter not found. Type: {property2.PropertyType}");
}
property2.SetValue(this, converter.ConvertFromInvariantString(item.Value), null);
}
}
}
I screen-shared with a colleague a couple days ago, and the problem was simply that I had two versions of a DLL in use. One version was being used in my main service, and the old version of the DLL was being used in the windows-service service that was already running, and which my main service in question was connecting to. That's why when I stepped into the method from the other windows service, the argument seemed to lose scope (perhaps it did actually lose scope). Once I made sure that the windows service had the correct reference to the updated DLL, everything mentioned here worked as expected.
As an aside, I later reproduced the error (more minimally) without even using the class-based field, and simply hard-coding a new Guid, like so: TradingCalendar = CalendarService.ClientProxy.Service.Calendars.GetCalendarByUidOrThrow(new Guid("e808b3fa-ab7c-48fc-8224-535e41393532"));
.