Line data Source code
1 : using System;
2 : using System.Collections.Generic;
3 : using System.Linq;
4 : using System.Reflection;
5 : using cdmdotnet.Logging;
6 : using Cqrs.Mongo.DataStores.Indexes;
7 : using Cqrs.Mongo.Serialisers;
8 : using MongoDB.Driver;
9 : using MongoDB.Driver.Builders;
10 :
11 : namespace Cqrs.Mongo.Factories
12 : {
13 : /// <summary>
14 : /// A factory for obtaining DataStore collections from Mongo
15 : /// </summary>
16 : public class MongoDataStoreFactory
17 1 : {
18 : private static IDictionary<Type, IList<object>> IndexTypesByEntityType { get; set; }
19 :
20 : protected ILogger Logger { get; private set; }
21 :
22 : protected IMongoDataStoreConnectionStringFactory MongoDataStoreConnectionStringFactory { get; private set; }
23 :
24 0 : public MongoDataStoreFactory(ILogger logger, IMongoDataStoreConnectionStringFactory mongoDataStoreConnectionStringFactory)
25 : {
26 : Logger = logger;
27 : MongoDataStoreConnectionStringFactory = mongoDataStoreConnectionStringFactory;
28 : }
29 :
30 : static MongoDataStoreFactory()
31 : {
32 : var typeSerializer = new TypeSerialiser();
33 : MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(Type), typeSerializer);
34 : MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(Type.GetType("System.RuntimeType"), typeSerializer);
35 :
36 : IndexTypesByEntityType = new Dictionary<Type, IList<object>>();
37 : foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
38 : {
39 : var mongoIndexTypes = assembly
40 : .GetTypes()
41 : .Where
42 : (
43 : type =>
44 : (
45 : // base is NOT an abstract index
46 : (
47 : type.BaseType != null &&
48 : type.BaseType.IsGenericType &&
49 : typeof(MongoIndex<>).IsAssignableFrom(type.BaseType.GetGenericTypeDefinition())
50 : )
51 : ||
52 : // base is an abstract index
53 : (
54 : type.BaseType != null &&
55 : type.BaseType.BaseType != null &&
56 : type.BaseType.BaseType.IsGenericType &&
57 : typeof(MongoIndex<>).IsAssignableFrom(type.BaseType.BaseType.GetGenericTypeDefinition())
58 : )
59 : ||
60 : // a deeper inheritance model
61 : (
62 : type.BaseType != null &&
63 : type.BaseType.BaseType != null &&
64 : type.BaseType.BaseType.BaseType != null &&
65 : type.BaseType.BaseType.BaseType.IsGenericType &&
66 : typeof(MongoIndex<>).IsAssignableFrom(type.BaseType.BaseType.BaseType.GetGenericTypeDefinition())
67 : )
68 : ||
69 : // an even deeper inheritance model
70 : (
71 : type.BaseType != null &&
72 : type.BaseType.BaseType != null &&
73 : type.BaseType.BaseType.BaseType != null &&
74 : type.BaseType.BaseType.BaseType.BaseType != null &&
75 : type.BaseType.BaseType.BaseType.BaseType.IsGenericType &&
76 : typeof(MongoIndex<>).IsAssignableFrom(type.BaseType.BaseType.BaseType.BaseType.GetGenericTypeDefinition())
77 : )
78 : )
79 : && !type.IsAbstract
80 : );
81 : foreach (Type mongoIndexType in mongoIndexTypes)
82 : {
83 : Type genericType = mongoIndexType;
84 : while (genericType != null && !genericType.IsGenericType)
85 : {
86 : genericType = genericType.BaseType;
87 : }
88 : genericType = genericType.GetGenericArguments().Single();
89 :
90 : IList<object> indexTypes;
91 : if (!IndexTypesByEntityType.TryGetValue(genericType, out indexTypes))
92 : IndexTypesByEntityType.Add(genericType, indexTypes = new List<object>());
93 : object mongoIndex = Activator.CreateInstance(mongoIndexType, true);
94 : indexTypes.Add(mongoIndex);
95 : }
96 : }
97 : }
98 :
99 0 : protected virtual MongoCollection<TEntity> GetCollection<TEntity>()
100 : {
101 : var mongoClient = new MongoClient(MongoDataStoreConnectionStringFactory.GetMongoConnectionString());
102 : MongoServer mongoServer = mongoClient.GetServer();
103 : MongoDatabase mongoDatabase = mongoServer.GetDatabase(MongoDataStoreConnectionStringFactory.GetMongoDatabaseName());
104 :
105 : return mongoDatabase.GetCollection<TEntity>(typeof(TEntity).FullName);
106 : }
107 :
108 0 : protected virtual void VerifyIndexes<TEntity>(MongoCollection<TEntity> collection)
109 : {
110 : Type entityType = typeof (TEntity);
111 : if (IndexTypesByEntityType.ContainsKey(entityType))
112 : {
113 : foreach (object untypedIndexType in IndexTypesByEntityType[entityType])
114 : {
115 : var mongoIndex = (MongoIndex<TEntity>)untypedIndexType;
116 :
117 : var indexKeysBuilder = new IndexKeysBuilder();
118 : if (mongoIndex.IsAcending)
119 : indexKeysBuilder = indexKeysBuilder.Ascending(mongoIndex.Selectors.ToArray());
120 : else
121 : indexKeysBuilder = indexKeysBuilder.Descending(mongoIndex.Selectors.ToArray());
122 :
123 : collection.CreateIndex
124 : (
125 : indexKeysBuilder,
126 : IndexOptions
127 : .SetUnique(mongoIndex.IsUnique)
128 : .SetName(mongoIndex.Name)
129 : );
130 : }
131 : }
132 : }
133 : }
134 : }
|