114 lines
4.5 KiB
C#
114 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using ln.bson.mapper.mappings;
|
|
|
|
namespace ln.bson.mapper
|
|
{
|
|
public class BsonMapper
|
|
{
|
|
private static BsonMapper _defaultInstance;
|
|
public static BsonMapper DefaultInstance
|
|
{
|
|
get
|
|
{
|
|
if (_defaultInstance is null)
|
|
_defaultInstance = new BsonMapper();
|
|
return _defaultInstance;
|
|
}
|
|
}
|
|
|
|
|
|
private Dictionary<Type, BsonMapping> _bsonMappings = new Dictionary<Type, BsonMapping>();
|
|
|
|
|
|
|
|
public BsonDocument Map<T>(T o) => Map(typeof(T), o);
|
|
public BsonDocument Map(object o) => Map(o.GetType(), o);
|
|
public BsonDocument Map(Type type, object o)
|
|
{
|
|
if (TryGetMapping(type, out BsonMapping bsonMapping))
|
|
{
|
|
if (bsonMapping.TryMapValue(this, o, out BsonValue bsonValue) &&
|
|
(bsonValue is BsonDocument bsonDocument))
|
|
return bsonDocument;
|
|
throw new FormatException("could not map object to BsonDocument");
|
|
}
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public T Unmap<T>(BsonDocument document) => (T)Unmap(typeof(T), document);
|
|
public object Unmap(Type type, BsonDocument document)
|
|
{
|
|
if (TryGetMapping(type, out BsonMapping bsonMapping) &&
|
|
bsonMapping.TryMapValue(this, document, out object o)
|
|
)
|
|
return o;
|
|
return null;
|
|
}
|
|
|
|
|
|
public bool TryGetMapping(Type type, out BsonMapping bsonMapping)
|
|
{
|
|
if (!_defaultMappings.TryGetValue(type, out bsonMapping) && !_bsonMappings.TryGetValue(type, out bsonMapping))
|
|
{
|
|
if (type.IsArray)
|
|
{
|
|
Type mappingType = typeof(ArrayMapping<>).MakeGenericType(type.GetElementType());
|
|
bsonMapping = (BsonMapping) Activator.CreateInstance(mappingType);
|
|
AddMapping(bsonMapping);
|
|
} else if (type.IsGenericType &&
|
|
type.GetGenericTypeDefinition().Equals(typeof(Dictionary<,>)) &&
|
|
type.GetGenericArguments()[0].Equals(typeof(string)))
|
|
{
|
|
Type mappingType = typeof(DictionaryMapping<>).MakeGenericType(type.GetGenericArguments()[1]);
|
|
bsonMapping = (BsonMapping)Activator.CreateInstance(mappingType);
|
|
AddMapping(bsonMapping);
|
|
} else if (type.IsGenericType &&
|
|
type.GetGenericTypeDefinition().Equals(typeof(IList<>)))
|
|
{
|
|
Type mappingType = typeof(IListMapping<,>).MakeGenericType(type, type.GetGenericArguments()[0]);
|
|
bsonMapping = (BsonMapping)Activator.CreateInstance(mappingType);
|
|
AddMapping(bsonMapping);
|
|
} else if (!type.IsPrimitive)
|
|
{
|
|
Type mappingType = typeof(ClassStructMapping<>).MakeGenericType(type);
|
|
bsonMapping = (BsonMapping) Activator.CreateInstance(mappingType);
|
|
AddMapping(bsonMapping);
|
|
} else
|
|
throw new NotSupportedException();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void AddMapping(BsonMapping bsonMapping) => AddMapping(bsonMapping, false);
|
|
public void AddMapping(BsonMapping bsonMapping, bool replace)
|
|
{
|
|
_bsonMappings.Add(bsonMapping.SourceType, bsonMapping);
|
|
}
|
|
|
|
public BsonMapping CreateMapping<T>()
|
|
{
|
|
if (TryGetMapping(typeof(T), out BsonMapping mapping))
|
|
return mapping;
|
|
return null;
|
|
}
|
|
|
|
|
|
private static Dictionary<Type, BsonMapping> _defaultMappings = new Dictionary<Type, BsonMapping>();
|
|
|
|
public static void AddDefaultMapping(BsonMapping bsonMapping) =>
|
|
_defaultMappings.Add(bsonMapping.SourceType, bsonMapping);
|
|
|
|
static BsonMapper()
|
|
{
|
|
AddDefaultMapping(new BsonMapping.Int32());
|
|
AddDefaultMapping(new BsonMapping.Int64());
|
|
AddDefaultMapping(new BsonMapping.Double());
|
|
AddDefaultMapping(new BsonMapping.String());
|
|
AddDefaultMapping(new BsonMapping.Guid());
|
|
AddDefaultMapping(new BsonMapping.Boolean());
|
|
AddDefaultMapping(new BsonMapping.Binary());
|
|
AddDefaultMapping(new BsonMapping.DateTime());
|
|
}
|
|
}
|
|
} |