Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mongodb C#驱动程序中引发自定义IBMSonSerializer异常_C#_Mongodb_Serialization - Fatal编程技术网

mongodb C#驱动程序中引发自定义IBMSonSerializer异常

mongodb C#驱动程序中引发自定义IBMSonSerializer异常,c#,mongodb,serialization,C#,Mongodb,Serialization,我已经为System.Security.Claims.Claims类编写了一个自定义IBsonSerializer,它非常臃肿,需要自定义反序列化。当作为一次性调用时,这是有效的,但是当注册它并从单元测试调用时,我遇到了问题,并且得到了可怕的异常“已经有一个为类型声明注册的序列化程序” 问题是,如果不创建序列化程序,似乎无法检查序列化程序是否已注册!我觉得这完全错了。如果调用BsonSerializer.LookupSerializer(),代码将调用BsonSerializerRegistry

我已经为
System.Security.Claims.Claims
类编写了一个自定义
IBsonSerializer
,它非常臃肿,需要自定义反序列化。当作为一次性调用时,这是有效的,但是当注册它并从单元测试调用时,我遇到了问题,并且得到了可怕的异常“已经有一个为类型声明注册的序列化程序”

问题是,如果不创建序列化程序,似乎无法检查序列化程序是否已注册!我觉得这完全错了。如果调用
BsonSerializer.LookupSerializer()
,代码将调用
BsonSerializerRegistry.GetSerializer()
,它将调用
GetOrAdd()
。换句话说,我无法检查然后添加自定义序列化程序,如果我不检查,如果再次添加,可能会出现错误

我错过了一些很明显的东西吗?单元测试是在多线程进程中调用的,因此即使我的安装程序在Startup.cs中,并且通常只调用一次,但在单元测试运行时也可以并行调用

lock (serializerLock)
{
    // I can't call the following, otherwise it creates a default serializer
    //if ( BsonSerializer.LookupSerializer<System.Security.Claims.Claim>().GetType() != typeof(MongoClaimSerializer))
    {
         BsonSerializer.RegisterSerializer(new MongoClaimSerializer());
    }
}
lock(序列化锁)
{
//我不能调用以下命令,否则它将创建一个默认序列化程序
//if(BsonSerializer.LookupSerializer().GetType()!=typeof(MongoClaimSerializer))
{
RegisterSerializer(新的MongoClaimSerializer());
}
}

以下代码应该为您需要的序列化程序注册和查找提供足够的封装

public static class SafeBsonSerializerRegistry
{
    private static ConcurrentDictionary<Type, IBsonSerializer> _cache = new ConcurrentDictionary<Type,IBsonSerializer>();

    public static IBsonSerializer<T> LookupSerializer<T>()
    {
         return (IBsonSerializer<T>)LookupSerializer(typeof(T));
    }

    public static IBsonSerializer LookupSerializer(Type type)
    {
        if (type == null)
            throw new ArgumentNullException("type");

        var typeInfo = type.GetTypeInfo();
        if (typeInfo.IsGenericType && typeInfo.ContainsGenericParameters)
        {
            var message = string.Format("Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type));
            throw new ArgumentException(message, "type");
        }

        IBsonSerializer serializer;

        if(_cache.TryGetValue(type, out serializer))
            return serializer;
        return null; //Note, this is where the BsonSerializerRegistry would GetOrAdd().
    }



    public static void RegisterSerializer<T>(IBsonSerializer<T> serializer)
    {
        RegisterSerializer(typeof(T), serializer);
    }

    public static void RegisterSerializer(Type type, IBsonSerializer serializer)
    {
        if (type == null)
            throw new ArgumentNullException("type");
        if (serializer == null)
            throw new ArgumentNullException("serializer");

        var typeInfo = type.GetTypeInfo();
        if (typeof(BsonValue).GetTypeInfo().IsAssignableFrom(type))
        {
            var message = string.Format("A serializer cannot be registered for type {0} because it is a subclass of BsonValue.", BsonUtils.GetFriendlyTypeName(type));
            throw new BsonSerializationException(message);
        }

        if (typeInfo.IsGenericType && typeInfo.ContainsGenericParameters)
        {
            var message = string.Format("Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type));
            throw new ArgumentException(message, "type");
        }

        if (!_cache.TryAdd(type, serializer))
        {
            var message = string.Format("There is already a serializer registered for type {0}.", BsonUtils.GetFriendlyTypeName(type));
            throw new BsonSerializationException(message);
        }

        //call to the actual BsonSerializer
        BsonSerializer.RegisterSerializer(type, serializer);
    }

}
公共静态类安全序列化注册表
{
私有静态ConcurrentDictionary_cache=新ConcurrentDictionary();
公共静态IBsonSerializer LookupSerializer()
{
return(IBsonSerializer)LookupSerializer(typeof(T));
}
公共静态IBMsonSerializer查找序列化程序(类型)
{
if(type==null)
抛出新的ArgumentNullException(“类型”);
var typeInfo=type.GetTypeInfo();
if(typeInfo.IsGenericType&&typeInfo.ContainsGenericParameters)
{
var message=string.Format(“泛型类型{0}具有未分配的类型参数。”,BsonUtils.GetFriendlyTypeName(类型));
抛出新的ArgumentException(消息,“type”);
}
IBsonSerializer;
if(_cache.TryGetValue(类型,输出序列化程序))
返回序列化程序;
return null;//注意,这是BsonSerializerRegistry获取Oradd()的地方。
}
公共静态无效寄存器序列化程序(IBMOSONSerializer序列化程序)
{
寄存器序列化器(typeof(T),序列化器);
}
公共静态void RegisterSerializer(类型类型,IBsonSerializer序列化器)
{
if(type==null)
抛出新的ArgumentNullException(“类型”);
if(序列化程序==null)
抛出新的ArgumentNullException(“序列化程序”);
var typeInfo=type.GetTypeInfo();
if(typeof(BsonValue).GetTypeInfo().IsAssignableFrom(type))
{
var message=string.Format(“无法为类型{0}注册序列化程序,因为它是BsonValue的子类。”,BsonUtils.GetFriendlyTypeName(类型));
抛出新的BsonSerializationException(消息);
}
if(typeInfo.IsGenericType&&typeInfo.ContainsGenericParameters)
{
var message=string.Format(“泛型类型{0}具有未分配的类型参数。”,BsonUtils.GetFriendlyTypeName(类型));
抛出新的ArgumentException(消息,“type”);
}
if(!\u cache.TryAdd(类型,序列化程序))
{
var message=string.Format(“已经为类型{0}注册了序列化程序。”,BsonUtils.GetFriendlyTypeName(类型));
抛出新的BsonSerializationException(消息);
}
//调用实际的BsonSerializer
注册表序列化程序(类型,序列化程序);
}
}
这不会替换现有的BsonSerializer或基础BsonSerializerRegistry。它只保证提供调用者的LookupSerializer方法首先使用它来注册它们


如果这不合适,请告诉我,我会回到绘图板上。

以下代码应该为您需要的序列化程序注册和查找提供足够的封装

public static class SafeBsonSerializerRegistry
{
    private static ConcurrentDictionary<Type, IBsonSerializer> _cache = new ConcurrentDictionary<Type,IBsonSerializer>();

    public static IBsonSerializer<T> LookupSerializer<T>()
    {
         return (IBsonSerializer<T>)LookupSerializer(typeof(T));
    }

    public static IBsonSerializer LookupSerializer(Type type)
    {
        if (type == null)
            throw new ArgumentNullException("type");

        var typeInfo = type.GetTypeInfo();
        if (typeInfo.IsGenericType && typeInfo.ContainsGenericParameters)
        {
            var message = string.Format("Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type));
            throw new ArgumentException(message, "type");
        }

        IBsonSerializer serializer;

        if(_cache.TryGetValue(type, out serializer))
            return serializer;
        return null; //Note, this is where the BsonSerializerRegistry would GetOrAdd().
    }



    public static void RegisterSerializer<T>(IBsonSerializer<T> serializer)
    {
        RegisterSerializer(typeof(T), serializer);
    }

    public static void RegisterSerializer(Type type, IBsonSerializer serializer)
    {
        if (type == null)
            throw new ArgumentNullException("type");
        if (serializer == null)
            throw new ArgumentNullException("serializer");

        var typeInfo = type.GetTypeInfo();
        if (typeof(BsonValue).GetTypeInfo().IsAssignableFrom(type))
        {
            var message = string.Format("A serializer cannot be registered for type {0} because it is a subclass of BsonValue.", BsonUtils.GetFriendlyTypeName(type));
            throw new BsonSerializationException(message);
        }

        if (typeInfo.IsGenericType && typeInfo.ContainsGenericParameters)
        {
            var message = string.Format("Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type));
            throw new ArgumentException(message, "type");
        }

        if (!_cache.TryAdd(type, serializer))
        {
            var message = string.Format("There is already a serializer registered for type {0}.", BsonUtils.GetFriendlyTypeName(type));
            throw new BsonSerializationException(message);
        }

        //call to the actual BsonSerializer
        BsonSerializer.RegisterSerializer(type, serializer);
    }

}
公共静态类安全序列化注册表
{
私有静态ConcurrentDictionary_cache=新ConcurrentDictionary();
公共静态IBsonSerializer LookupSerializer()
{
return(IBsonSerializer)LookupSerializer(typeof(T));
}
公共静态IBMsonSerializer查找序列化程序(类型)
{
if(type==null)
抛出新的ArgumentNullException(“类型”);
var typeInfo=type.GetTypeInfo();
if(typeInfo.IsGenericType&&typeInfo.ContainsGenericParameters)
{
var message=string.Format(“泛型类型{0}具有未分配的类型参数。”,BsonUtils.GetFriendlyTypeName(类型));
抛出新的ArgumentException(消息,“type”);
}
IBsonSerializer;
if(_cache.TryGetValue(类型,输出序列化程序))
返回序列化程序;
return null;//注意,这是BsonSerializerRegistry获取Oradd()的地方。
}
公共静态无效寄存器序列化程序(IBMOSONSerializer序列化程序)
{
寄存器序列化器(typeof(T),序列化器);
}
公共静态void RegisterSerializer(类型类型,IBsonSerializer序列化器)
{
if(type==null)
抛出新的ArgumentNullException(“类型”);
if(序列化程序==null)
抛出新的ArgumentNullException(“序列化程序”);
var typeInfo=type.GetTypeInfo();
if(typeof(BsonValue).GetTypeInfo().IsAssignableFrom(type))
{
var message=string.Format(“无法为类型{0}注册序列化程序,因为它是BsonValue的子类。”,BsonUtils.GetFriendlyTypeName(类型));