情况:
我们目前有一个MVC网站,它从xml架构到对象模型进行序列化和反序列化。其中一些对象具有ID属性,该属性是xml中的属性。
要求:
我们需要确保xml中的每个ID都是唯一的。对象在服务器端代码中添加到我们的模式模型中,然后使用XMLSerializer进行序列化。这些对象ID必须在序列化之前设置,因为我们在构建被序列化的对象时在其他时间使用它们。因此,理想情况下,他们需要设置对象创建。
此对象模型也被与其他DLL项目使用的网站无关的代码使用。因此,在对象中使用诸如会话状态之类的东西来跟踪ID等并不是一个真正的选择。
限制: 看来xmlserialiser要求要序列化和反序列化的对象提供无参数构造函数。因此,我们无法强制我们的对象采用任何类型的IDGenerator。我想我们可以有两个构造函数,但程序员必须记住调用一个构造函数。
解决: 我们创建了一个静态类,在我们的对象模型的构造函数中使用。这可确保ID始终递增。这也意味着在我们的代码中创建一个新对象时,我们不必担心正在创建的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中查找当前的最大属性,以便始终从中开始。每次反序列化我们的XML后都会调用SetMinimumIdentity(),这样每当我们从那里创建新对象时,我们的ID至少为MAX + 1;
即。 ObjectModel obj = new ObjectModel();
确保MAX + 1的ID作为ObjectModel的构造函数是这样的:
public partial class ObjectModel
{
public OverseerObjectIDType()
{
ID = IdGenerator.NextId();
}
}
我们的问题: 问题似乎在于我们使用静态变量来包含用于创建ID的_value属性。由于这是在我们的网站上运行,变量在所有用户之间共享,因此每次用户执行某些操作时都会调整/重置变量。这会影响其他用户,即使他们的最大ID等完全不同。
理想的解决方案: 我们希望确保生成唯一ID,但生成的ID仅基于当前用户的XML设置。因此,我们可能希望放弃使用静力学。但是,我们不希望明确地在从ObjectModel继承的每个对象上设置它,因为这意味着我们必须记住每次创建新对象时都设置ID。
有没有人有任何想法可以提供帮助?这有点难以解释,所以如果它没有意义让我知道,我会相应更新。
更新:
在Mortens建议我现在使用Interlocked来增加变量计数器。
更新: 我也可能会指出xml 可能原始是在我们的环境之外生成的,所以我们最初没有控制存储在ObjectModel模式元素上的ID int值。