Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="cdmdotnet Limited">
4 : // // Copyright cdmdotnet Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections.Generic;
11 : using System.Linq;
12 : using System.Linq.Expressions;
13 : using System.Reflection;
14 : using cdmdotnet.Logging;
15 : using Cqrs.MongoDB.DataStores.Indexes;
16 : using Cqrs.MongoDB.Serialisers;
17 : using MongoDB.Driver;
18 : using MongoDB.Bson.Serialization;
19 :
20 : namespace Cqrs.MongoDB.Factories
21 : {
22 : /// <summary>
23 : /// A factory for obtaining DataStore collections from Mongo
24 : /// </summary>
25 : public class MongoDbDataStoreFactory
26 1 : {
27 : internal static IDictionary<Type, IList<object>> IndexTypesByEntityType { get; set; }
28 :
29 : protected ILogger Logger { get; private set; }
30 :
31 : protected IMongoDbDataStoreConnectionStringFactory MongoDbDataStoreConnectionStringFactory { get; private set; }
32 :
33 0 : public MongoDbDataStoreFactory(ILogger logger, IMongoDbDataStoreConnectionStringFactory mongoDbDataStoreConnectionStringFactory)
34 : {
35 : Logger = logger;
36 : MongoDbDataStoreConnectionStringFactory = mongoDbDataStoreConnectionStringFactory;
37 : }
38 :
39 : static MongoDbDataStoreFactory()
40 : {
41 : var typeSerializer = new TypeSerialiser();
42 : BsonSerializer.RegisterSerializer(typeof(Type), typeSerializer);
43 : BsonSerializer.RegisterSerializer(Type.GetType("System.RuntimeType"), typeSerializer);
44 :
45 : IndexTypesByEntityType = new Dictionary<Type, IList<object>>();
46 : foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
47 : {
48 : var mongoIndexTypes = assembly
49 : .GetTypes()
50 : .Where
51 : (
52 : type =>
53 : (
54 : // base is NOT an abstract index
55 : (
56 : type.BaseType != null &&
57 : type.BaseType.IsGenericType &&
58 : typeof(MongoDbIndex<>).IsAssignableFrom(type.BaseType.GetGenericTypeDefinition())
59 : )
60 : ||
61 : // base is an abstract index
62 : (
63 : type.BaseType != null &&
64 : type.BaseType.BaseType != null &&
65 : type.BaseType.BaseType.IsGenericType &&
66 : typeof(MongoDbIndex<>).IsAssignableFrom(type.BaseType.BaseType.GetGenericTypeDefinition())
67 : )
68 : ||
69 : // a deeper inheritance model
70 : (
71 : type.BaseType != null &&
72 : type.BaseType.BaseType != null &&
73 : type.BaseType.BaseType.BaseType != null &&
74 : type.BaseType.BaseType.BaseType.IsGenericType &&
75 : typeof(MongoDbIndex<>).IsAssignableFrom(type.BaseType.BaseType.BaseType.GetGenericTypeDefinition())
76 : )
77 : ||
78 : // an even deeper inheritance model
79 : (
80 : type.BaseType != null &&
81 : type.BaseType.BaseType != null &&
82 : type.BaseType.BaseType.BaseType != null &&
83 : type.BaseType.BaseType.BaseType.BaseType != null &&
84 : type.BaseType.BaseType.BaseType.BaseType.IsGenericType &&
85 : typeof(MongoDbIndex<>).IsAssignableFrom(type.BaseType.BaseType.BaseType.BaseType.GetGenericTypeDefinition())
86 : )
87 : )
88 : && !type.IsAbstract
89 : );
90 : foreach (Type mongoIndexType in mongoIndexTypes)
91 : {
92 : Type genericType = mongoIndexType;
93 : while (genericType != null && !genericType.IsGenericType)
94 : {
95 : genericType = genericType.BaseType;
96 : }
97 : genericType = genericType.GetGenericArguments().Single();
98 :
99 : IList<object> indexTypes;
100 : if (!IndexTypesByEntityType.TryGetValue(genericType, out indexTypes))
101 : IndexTypesByEntityType.Add(genericType, indexTypes = new List<object>());
102 : object mongoIndex = Activator.CreateInstance(mongoIndexType, true);
103 : indexTypes.Add(mongoIndex);
104 : }
105 : }
106 : }
107 :
108 0 : protected virtual IMongoCollection<TEntity> GetCollection<TEntity>()
109 : {
110 : var mongoClient = new MongoClient(MongoDbDataStoreConnectionStringFactory.GetDataStoreConnectionString());
111 : IMongoDatabase mongoDatabase = mongoClient.GetDatabase(MongoDbDataStoreConnectionStringFactory.GetDataStoreDatabaseName());
112 :
113 : return mongoDatabase.GetCollection<TEntity>(typeof(TEntity).FullName);
114 : }
115 :
116 0 : protected virtual void VerifyIndexes<TEntity>(IMongoCollection<TEntity> collection)
117 : {
118 : Type entityType = typeof (TEntity);
119 : if (IndexTypesByEntityType.ContainsKey(entityType))
120 : {
121 : foreach (object untypedIndexType in IndexTypesByEntityType[entityType])
122 : {
123 : var mongoIndex = (MongoDbIndex<TEntity>)untypedIndexType;
124 :
125 : IndexKeysDefinitionBuilder<TEntity> indexKeysBuilder = Builders<TEntity>.IndexKeys;
126 : IndexKeysDefinition<TEntity> indexKey = null;
127 :
128 : IList<Expression<Func<TEntity, object>>> selectors = mongoIndex.Selectors.ToList();
129 : for (int i = 0; i < selectors.Count; i++)
130 : {
131 : Expression<Func<TEntity, object>> expression = selectors[i];
132 : if (mongoIndex.IsAcending)
133 : {
134 : if (i == 0)
135 : indexKey = indexKeysBuilder.Ascending(expression);
136 : else
137 : indexKey = indexKey.Ascending(expression);
138 : }
139 : else
140 : {
141 : if (i == 0)
142 : indexKey = indexKeysBuilder.Descending(expression);
143 : else
144 : indexKey = indexKey.Descending(expression);
145 : }
146 : }
147 :
148 : collection.Indexes.CreateOne
149 : (
150 : indexKey,
151 : new CreateIndexOptions
152 : {
153 : Unique = mongoIndex.IsUnique,
154 : Name = mongoIndex.Name
155 : }
156 : );
157 : }
158 : }
159 : }
160 : }
161 : }
|