Ситуация:
В настоящее время у нас есть веб-сайт MVC, который сериализует и десериализует из XML-схемы в объектную модель.Некоторые из этих объектов имеют свойство ID, являющееся атрибутом в XML.
Требование:
Нам необходимо убедиться, что каждый идентификатор в XML уникален.Объекты добавляются в нашу модель схемы в коде на стороне сервера, а затем сериализуются с использованием XMLSerializer.Эти идентификаторы объекта должны быть установлены до сериализации, поскольку мы используем их в другое время при создании сериализуемого объекта.Следовательно, в идеале их необходимо устанавливать при создании объекта.
Эта объектная модель также используется кодом, который не связан с веб-сайтом, поскольку используется другим проектом DLL.Поэтому использование таких вещей, как состояние сеанса внутри объектов для отслеживания идентификаторов и т. Д., На самом деле не вариант.
Ограничение: Может показаться, что xmlserialiser требует, чтобы объекты были сериализованы и десериализованы;конструктор без параметров.Таким образом, мы не можем заставить наши объекты принимать какие-либо IDGenerator.Я предполагаю, что у нас может быть два конструктора, но программистам придется помнить, чтобы вызывать запись.
Разрешение: Мы создали статический класс, который используется в конструкторе наших объектных моделей.Это гарантирует, что ID увеличиваются все время.Это также означает, что при создании нового объекта в нашем коде нам не нужно беспокоиться об идентификаторе, который создается при создании конструктора.
Код:
internal static class IdGenerator
{
private static int Min = 0x8000; //0xA0000;
private static int Max = 0xFFFF9;
private static int _value = Min - 1;
private static int _objectIterations = 0;
public static int NextId()
{
if (_value < Max)
{
Interlocked.Increment(ref _value);
}
else
{
_value = Min;
}
return _value;
}
/// <summary>
/// Navigates the schema tree and returns the maxium value from properties identified with the SchemaObjectIdentity attribute
/// </summary>
/// <param name="scenario"></param>
/// <returns></returns>
public static void SetMinimumIdentity(ObjectModel analysis, int minimum)
{
int currentMax = minimum;
PropertyMax<ObjectModel>(analysis, ref currentMax);
if (_value < currentMax)
_value = currentMax + 1;
}
}
PropertyMax - это метод, который используется для поиска текущего максимального свойства в нашей ObjectModel, так что мы всегда начинаем с этого.SetMinimumIdentity () вызывается после каждой десериализации нашего XML, так что всякий раз, когда мы создаем оттуда новые объекты, у нас есть ID, по крайней мере, MAX + 1;
т.е. ObjectModel obj = new ObjectModel ();
Удостоверится, что идентификатор MAX + 1 в качестве конструктора для ObjectModel таков:
public partial class ObjectModel
{
public OverseerObjectIDType()
{
ID = IdGenerator.NextId();
}
}
Наша проблема: Проблема, похоже, заключается в использовании статических переменных длясодержит свойство _value, используемое для создания идентификаторов.Поскольку это выполняется на нашем веб-сайте, эта переменная является общей для всех пользователей, и поэтому она устанавливается / сбрасывается каждый раз, когда пользователь что-то делает.Это влияет на других пользователей, даже если их максимальные идентификаторы и т. Д. Совершенно разные.
Желаемое решение: Мы хотим обеспечить генерацию уникального идентификатора, но сгенерированные идентификаторы основаны только на настройке XML текущих пользователей,Следовательно, мы, вероятно, хотим отказаться от использования статики.Однако мы не хотим, чтобы эксплицит устанавливал это для каждого объекта, унаследованного от ObjectModel, поскольку это означает, что мы должны помнить об установке идентификатора каждый раз, когда создаем новый объект.
Есть ли у кого-нибудь идеи, которые могли быПомогите?Это немного сложно объяснить, поэтому, если это не имеет смысла, дайте мне знать, и я обновлю соответствующим образом.
ОБНОВЛЕНИЕ:
В предложении Мортенса я теперь использую Interlocked для увеличения счетчика переменных.
ОБНОВЛЕНИЕ: Я также мог бы указать, что оригинал xml может быть сгенерирован вне нашей среды, поэтому мы изначально не имеем никакого контроля над значениями ID int, хранящимися в элементах схемы ObjectModel.