PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/src/FluentNHibernate/Testing/PersistenceSpecificationExtensions.cs

http://github.com/jagregory/fluent-nhibernate
C# | 517 lines | 413 code | 85 blank | 19 comment | 20 complexity | 510237af71d518e1e7100ace93047021 MD5 | raw file
Possible License(s): BSD-3-Clause, CC-BY-SA-3.0, Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using FluentNHibernate.Testing.Values;
  6. using FluentNHibernate.Utils;
  7. using System.Collections;
  8. using FluentNHibernate.Utils.Reflection;
  9. namespace FluentNHibernate.Testing
  10. {
  11. public static class PersistenceSpecificationExtensions
  12. {
  13. public static PersistenceSpecification<T> CheckProperty<T>(this PersistenceSpecification<T> spec,
  14. Expression<Func<T, object>> expression, object propertyValue)
  15. {
  16. return spec.CheckProperty(expression, propertyValue, (IEqualityComparer)null);
  17. }
  18. public static PersistenceSpecification<T> CheckProperty<T>(this PersistenceSpecification<T> spec,
  19. Expression<Func<T, object>> expression, object propertyValue,
  20. IEqualityComparer propertyComparer)
  21. {
  22. Accessor property = ReflectionHelper.GetAccessor(expression);
  23. return spec.RegisterCheckedProperty(new Property<T, object>(property, propertyValue), propertyComparer);
  24. }
  25. public static PersistenceSpecification<T> CheckProperty<T, TListElement>(this PersistenceSpecification<T> spec,
  26. Expression<Func<T, Array>> expression,
  27. IEnumerable<TListElement> propertyValue)
  28. {
  29. return spec.CheckProperty(expression, propertyValue, null);
  30. }
  31. public static PersistenceSpecification<T> CheckProperty<T, TListElement>(this PersistenceSpecification<T> spec,
  32. Expression<Func<T, Array>> expression,
  33. IEnumerable<TListElement> propertyValue,
  34. IEqualityComparer elementComparer)
  35. {
  36. Accessor property = ReflectionHelper.GetAccessor(expression);
  37. return spec.RegisterCheckedProperty(new List<T, TListElement>(property, propertyValue), elementComparer);
  38. }
  39. public static PersistenceSpecification<T> CheckProperty<T, TProperty>(this PersistenceSpecification<T> spec,
  40. Expression<Func<T, TProperty>> expression,
  41. TProperty propertyValue,
  42. Action<T, TProperty> propertySetter)
  43. {
  44. return spec.CheckProperty(expression, propertyValue, null, propertySetter);
  45. }
  46. public static PersistenceSpecification<T> CheckProperty<T, TProperty>(this PersistenceSpecification<T> spec,
  47. Expression<Func<T, TProperty>> expression,
  48. TProperty propertyValue,
  49. IEqualityComparer propertyComparer,
  50. Action<T, TProperty> propertySetter)
  51. {
  52. Accessor propertyInfoFromExpression = ReflectionHelper.GetAccessor(expression);
  53. var property = new Property<T, TProperty>(propertyInfoFromExpression, propertyValue);
  54. property.ValueSetter = (target, propertyInfo, value) => propertySetter(target, value);
  55. return spec.RegisterCheckedProperty(property, propertyComparer);
  56. }
  57. public static PersistenceSpecification<T> CheckReference<T>(this PersistenceSpecification<T> spec,
  58. Expression<Func<T, object>> expression,
  59. object propertyValue)
  60. {
  61. return spec.CheckReference(expression, propertyValue, (IEqualityComparer)null);
  62. }
  63. public static PersistenceSpecification<T> CheckReference<T>(this PersistenceSpecification<T> spec,
  64. Expression<Func<T, object>> expression,
  65. object propertyValue,
  66. IEqualityComparer propertyComparer)
  67. {
  68. Accessor property = ReflectionHelper.GetAccessor(expression);
  69. return spec.RegisterCheckedProperty(new ReferenceProperty<T, object>(property, propertyValue), propertyComparer);
  70. }
  71. public static PersistenceSpecification<T> CheckReference<T, TReference>(this PersistenceSpecification<T> spec,
  72. Expression<Func<T, object>> expression,
  73. TReference propertyValue,
  74. params Func<TReference, object>[] propertiesToCompare)
  75. {
  76. // Because of the params keyword, the compiler will select this overload
  77. // instead of the one above, even when no funcs are supplied in the method call.
  78. if (propertiesToCompare == null || propertiesToCompare.Length == 0)
  79. return spec.CheckReference(expression, propertyValue, (IEqualityComparer)null);
  80. return spec.CheckReference(expression, propertyValue, new FuncEqualityComparer<TReference>(propertiesToCompare));
  81. }
  82. public static PersistenceSpecification<T> CheckReference<T, TProperty>(this PersistenceSpecification<T> spec,
  83. Expression<Func<T, TProperty>> expression,
  84. TProperty propertyValue,
  85. Action<T, TProperty> propertySetter)
  86. {
  87. return spec.CheckReference(expression, propertyValue, null, propertySetter);
  88. }
  89. public static PersistenceSpecification<T> CheckReference<T, TProperty>(this PersistenceSpecification<T> spec,
  90. Expression<Func<T, TProperty>> expression,
  91. TProperty propertyValue,
  92. IEqualityComparer propertyComparer,
  93. Action<T, TProperty> propertySetter)
  94. {
  95. Accessor propertyInfoFromExpression = ReflectionHelper.GetAccessor(expression);
  96. var property = new ReferenceProperty<T, TProperty>(propertyInfoFromExpression, propertyValue);
  97. property.ValueSetter = (target, propertyInfo, value) => propertySetter(target, value);
  98. return spec.RegisterCheckedProperty(property, propertyComparer);
  99. }
  100. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  101. Expression<Func<T, IEnumerable<TListElement>>> expression,
  102. IEnumerable<TListElement> propertyValue)
  103. {
  104. return spec.CheckList(expression, propertyValue, (IEqualityComparer)null);
  105. }
  106. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  107. Expression<Func<T, IEnumerable<TListElement>>> expression,
  108. IEnumerable<TListElement> propertyValue,
  109. IEqualityComparer elementComparer)
  110. {
  111. Accessor property = ReflectionHelper.GetAccessor(expression);
  112. return spec.RegisterCheckedProperty(new ReferenceList<T, TListElement>(property, propertyValue), elementComparer);
  113. }
  114. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  115. Expression<Func<T, IEnumerable<TListElement>>> expression,
  116. IEnumerable<TListElement> propertyValue,
  117. params Func<TListElement, object>[] propertiesToCompare)
  118. {
  119. // Because of the params keyword, the compiler can select this overload
  120. // instead of the one above, even when no funcs are supplied in the method call.
  121. if (propertiesToCompare == null || propertiesToCompare.Length == 0)
  122. return spec.CheckList(expression, propertyValue, (IEqualityComparer)null);
  123. return spec.CheckList(expression, propertyValue, new FuncEqualityComparer<TListElement>(propertiesToCompare));
  124. }
  125. public static PersistenceSpecification<T> CheckInverseList<T, TListElement>(this PersistenceSpecification<T> spec,
  126. Expression<Func<T, IEnumerable<TListElement>>> expression,
  127. IEnumerable<TListElement> propertyValue,
  128. IEqualityComparer elementComparer)
  129. {
  130. Accessor property = ReflectionHelper.GetAccessor(expression);
  131. return spec.RegisterCheckedPropertyWithoutTransactionalSave(new ReferenceList<T, TListElement>(property, propertyValue), elementComparer);
  132. }
  133. public static PersistenceSpecification<T> CheckInverseList<T, TListElement>(this PersistenceSpecification<T> spec,
  134. Expression<Func<T, IEnumerable<TListElement>>> expression,
  135. IEnumerable<TListElement> propertyValue,
  136. params Func<TListElement, object>[] propertiesToCompare)
  137. {
  138. // Because of the params keyword, the compiler can select this overload
  139. // instead of the one above, even when no funcs are supplied in the method call.
  140. if (propertiesToCompare == null || propertiesToCompare.Length == 0)
  141. return spec.CheckList(expression, propertyValue, (IEqualityComparer)null);
  142. return spec.CheckInverseList(expression, propertyValue, new FuncEqualityComparer<TListElement>(propertiesToCompare));
  143. }
  144. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  145. Expression<Func<T, IEnumerable<TListElement>>> expression,
  146. IEnumerable<TListElement> propertyValue,
  147. Action<T, TListElement> listItemSetter)
  148. {
  149. return spec.CheckList(expression, propertyValue, null, listItemSetter);
  150. }
  151. public static PersistenceSpecification<T> CheckInverseList<T, TListElement>(this PersistenceSpecification<T> spec,
  152. Expression<Func<T, IEnumerable<TListElement>>> expression,
  153. IEnumerable<TListElement> propertyValue,
  154. Action<T, TListElement> listItemSetter)
  155. {
  156. return spec.CheckInverseList(expression, propertyValue, null, listItemSetter);
  157. }
  158. public static PersistenceSpecification<T> CheckInverseList<T, TListElement>(this PersistenceSpecification<T> spec,
  159. Expression<Func<T, IEnumerable<TListElement>>> expression,
  160. IEnumerable<TListElement> propertyValue,
  161. IEqualityComparer elementComparer,
  162. Action<T, TListElement> listItemSetter)
  163. {
  164. Accessor property = ReflectionHelper.GetAccessor(expression);
  165. var list = new ReferenceList<T, TListElement>(property, propertyValue);
  166. list.ValueSetter = (target, propertyInfo, value) =>
  167. {
  168. foreach (var item in value)
  169. {
  170. listItemSetter(target, item);
  171. }
  172. };
  173. return spec.RegisterCheckedPropertyWithoutTransactionalSave(list, elementComparer);
  174. }
  175. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  176. Expression<Func<T, IEnumerable<TListElement>>> expression,
  177. IEnumerable<TListElement> propertyValue,
  178. IEqualityComparer elementComparer,
  179. Action<T, TListElement> listItemSetter)
  180. {
  181. Accessor property = ReflectionHelper.GetAccessor(expression);
  182. var list = new ReferenceList<T, TListElement>(property, propertyValue);
  183. list.ValueSetter = (target, propertyInfo, value) =>
  184. {
  185. foreach(var item in value)
  186. {
  187. listItemSetter(target, item);
  188. }
  189. };
  190. return spec.RegisterCheckedProperty(list, elementComparer);
  191. }
  192. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  193. Expression<Func<T, IEnumerable<TListElement>>> expression,
  194. IEnumerable<TListElement> propertyValue,
  195. Action<T, IEnumerable<TListElement>> listSetter)
  196. {
  197. return spec.CheckList(expression, propertyValue, null, listSetter);
  198. }
  199. public static PersistenceSpecification<T> CheckList<T, TListElement>(this PersistenceSpecification<T> spec,
  200. Expression<Func<T, IEnumerable<TListElement>>> expression,
  201. IEnumerable<TListElement> propertyValue,
  202. IEqualityComparer elementComparer,
  203. Action<T, IEnumerable<TListElement>> listSetter)
  204. {
  205. Accessor property = ReflectionHelper.GetAccessor(expression);
  206. var list = new ReferenceList<T, TListElement>(property, propertyValue);
  207. list.ValueSetter = (target, propertyInfo, value) => listSetter(target, value);
  208. return spec.RegisterCheckedProperty(list, elementComparer);
  209. }
  210. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  211. Expression<Func<T, IEnumerable<TListElement>>> expression,
  212. IEnumerable<TListElement> propertyValue)
  213. {
  214. return spec.CheckInverseBag(expression, propertyValue, (IEqualityComparer)null);
  215. }
  216. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  217. Expression<Func<T, IEnumerable<TListElement>>> expression,
  218. IEnumerable<TListElement> propertyValue,
  219. IEqualityComparer elementComparer)
  220. {
  221. Accessor property = ReflectionHelper.GetAccessor(expression);
  222. return spec.RegisterCheckedPropertyWithoutTransactionalSave(new ReferenceBag<T, TListElement>(property, propertyValue), elementComparer);
  223. }
  224. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  225. Expression<Func<T, IEnumerable<TListElement>>> expression,
  226. IEnumerable<TListElement> propertyValue,
  227. params Func<TListElement, object>[] propertiesToCompare)
  228. {
  229. // Because of the params keyword, the compiler can select this overload
  230. // instead of the one above, even when no funcs are supplied in the method call.
  231. if (propertiesToCompare == null || propertiesToCompare.Length == 0)
  232. return spec.CheckInverseBag(expression, propertyValue, (IEqualityComparer)null);
  233. return spec.CheckInverseBag(expression, propertyValue, new FuncEqualityComparer<TListElement>(propertiesToCompare));
  234. }
  235. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  236. Expression<Func<T, IEnumerable<TListElement>>> expression,
  237. IEnumerable<TListElement> propertyValue,
  238. Action<T, TListElement> listItemSetter)
  239. {
  240. return spec.CheckInverseBag(expression, propertyValue, null, listItemSetter);
  241. }
  242. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  243. Expression<Func<T, IEnumerable<TListElement>>> expression,
  244. IEnumerable<TListElement> propertyValue,
  245. Action<T, IEnumerable<TListElement>> listSetter)
  246. {
  247. return spec.CheckInverseBag(expression, propertyValue, null, listSetter);
  248. }
  249. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  250. Expression<Func<T, IEnumerable<TListElement>>> expression,
  251. IEnumerable<TListElement> propertyValue,
  252. IEqualityComparer elementComparer,
  253. Action<T, TListElement> listItemSetter)
  254. {
  255. Accessor property = ReflectionHelper.GetAccessor(expression);
  256. var list = new ReferenceBag<T, TListElement>(property, propertyValue);
  257. list.ValueSetter = (target, propertyInfo, value) =>
  258. {
  259. foreach (var item in value)
  260. {
  261. listItemSetter(target, item);
  262. }
  263. };
  264. return spec.RegisterCheckedPropertyWithoutTransactionalSave(list, elementComparer);
  265. }
  266. public static PersistenceSpecification<T> CheckInverseBag<T, TListElement>(this PersistenceSpecification<T> spec,
  267. Expression<Func<T, IEnumerable<TListElement>>> expression,
  268. IEnumerable<TListElement> propertyValue,
  269. IEqualityComparer elementComparer,
  270. Action<T, IEnumerable<TListElement>> listSetter)
  271. {
  272. Accessor property = ReflectionHelper.GetAccessor(expression);
  273. var list = new ReferenceBag<T, TListElement>(property, propertyValue);
  274. list.ValueSetter = (target, propertyInfo, value) => listSetter(target, value);
  275. return spec.RegisterCheckedPropertyWithoutTransactionalSave(list, elementComparer);
  276. }
  277. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  278. Expression<Func<T, IEnumerable<TListElement>>> expression,
  279. IEnumerable<TListElement> propertyValue)
  280. {
  281. return spec.CheckBag(expression, propertyValue, (IEqualityComparer)null);
  282. }
  283. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  284. Expression<Func<T, IEnumerable<TListElement>>> expression,
  285. IEnumerable<TListElement> propertyValue,
  286. IEqualityComparer elementComparer)
  287. {
  288. Accessor property = ReflectionHelper.GetAccessor(expression);
  289. return spec.RegisterCheckedProperty(new ReferenceBag<T, TListElement>(property, propertyValue), elementComparer);
  290. }
  291. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  292. Expression<Func<T, IEnumerable<TListElement>>> expression,
  293. IEnumerable<TListElement> propertyValue,
  294. params Func<TListElement, object>[] propertiesToCompare)
  295. {
  296. // Because of the params keyword, the compiler can select this overload
  297. // instead of the one above, even when no funcs are supplied in the method call.
  298. if (propertiesToCompare == null || propertiesToCompare.Length == 0)
  299. return spec.CheckBag(expression, propertyValue, (IEqualityComparer)null);
  300. return spec.CheckBag(expression, propertyValue, new FuncEqualityComparer<TListElement>(propertiesToCompare));
  301. }
  302. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  303. Expression<Func<T, IEnumerable<TListElement>>> expression,
  304. IEnumerable<TListElement> propertyValue,
  305. Action<T, TListElement> listItemSetter)
  306. {
  307. return spec.CheckBag(expression, propertyValue, null, listItemSetter);
  308. }
  309. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  310. Expression<Func<T, IEnumerable<TListElement>>> expression,
  311. IEnumerable<TListElement> propertyValue,
  312. Action<T, IEnumerable<TListElement>> listSetter)
  313. {
  314. return spec.CheckBag(expression, propertyValue, null, listSetter);
  315. }
  316. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  317. Expression<Func<T, IEnumerable<TListElement>>> expression,
  318. IEnumerable<TListElement> propertyValue,
  319. IEqualityComparer elementComparer,
  320. Action<T, TListElement> listItemSetter)
  321. {
  322. Accessor property = ReflectionHelper.GetAccessor(expression);
  323. var list = new ReferenceBag<T, TListElement>(property, propertyValue);
  324. list.ValueSetter = (target, propertyInfo, value) =>
  325. {
  326. foreach (var item in value)
  327. {
  328. listItemSetter(target, item);
  329. }
  330. };
  331. return spec.RegisterCheckedProperty(list, elementComparer);
  332. }
  333. public static PersistenceSpecification<T> CheckBag<T, TListElement>(this PersistenceSpecification<T> spec,
  334. Expression<Func<T,IEnumerable<TListElement>>> expression,
  335. IEnumerable<TListElement> propertyValue,
  336. IEqualityComparer elementComparer,
  337. Action<T, IEnumerable<TListElement>> listSetter)
  338. {
  339. Accessor property = ReflectionHelper.GetAccessor(expression);
  340. var list = new ReferenceBag<T, TListElement>(property, propertyValue);
  341. list.ValueSetter = (target, propertyInfo, value) => listSetter(target, value);
  342. return spec.RegisterCheckedProperty(list, elementComparer);
  343. }
  344. public static PersistenceSpecification<T> CheckComponentList<T, TListElement>(this PersistenceSpecification<T> spec,
  345. Expression<Func<T, object>> expression,
  346. IEnumerable<TListElement> propertyValue)
  347. {
  348. return spec.CheckComponentList(expression, propertyValue, null);
  349. }
  350. /// <summary>
  351. /// Checks a list of components for validity.
  352. /// </summary>
  353. /// <typeparam name="T">Entity type</typeparam>
  354. /// <typeparam name="TListElement">Type of list element</typeparam>
  355. /// <param name="spec">Persistence specification</param>
  356. /// <param name="expression">Property</param>
  357. /// <param name="propertyValue">Value to save</param>
  358. /// <param name="elementComparer">Equality comparer</param>
  359. public static PersistenceSpecification<T> CheckComponentList<T, TListElement>(this PersistenceSpecification<T> spec,
  360. Expression<Func<T, object>> expression,
  361. IEnumerable<TListElement> propertyValue,
  362. IEqualityComparer elementComparer)
  363. {
  364. Accessor property = ReflectionHelper.GetAccessor(expression);
  365. return spec.RegisterCheckedProperty(new List<T, TListElement>(property, propertyValue), elementComparer);
  366. }
  367. public static PersistenceSpecification<T> CheckComponentList<T, TListElement>(this PersistenceSpecification<T> spec,
  368. Expression<Func<T, IEnumerable<TListElement>>> expression,
  369. IEnumerable<TListElement> propertyValue,
  370. Action<T, TListElement> listItemSetter)
  371. {
  372. return spec.CheckComponentList(expression, propertyValue, null, listItemSetter);
  373. }
  374. public static PersistenceSpecification<T> CheckComponentList<T, TListElement>(this PersistenceSpecification<T> spec,
  375. Expression<Func<T, IEnumerable<TListElement>>> expression,
  376. IEnumerable<TListElement> propertyValue,
  377. IEqualityComparer elementComparer,
  378. Action<T, TListElement> listItemSetter)
  379. {
  380. Accessor property = ReflectionHelper.GetAccessor(expression);
  381. var list = new List<T, TListElement>(property, propertyValue);
  382. list.ValueSetter = (target, propertyInfo, value) => {
  383. foreach(var item in value) {
  384. listItemSetter(target, item);
  385. }
  386. };
  387. return spec.RegisterCheckedProperty(list, elementComparer);
  388. }
  389. public static PersistenceSpecification<T> CheckComponentList<T, TListElement>(this PersistenceSpecification<T> spec,
  390. Expression<Func<T, IEnumerable<TListElement>>> expression,
  391. IEnumerable<TListElement> propertyValue,
  392. Action<T, IEnumerable<TListElement>> listSetter)
  393. {
  394. return spec.CheckComponentList(expression, propertyValue, null, listSetter);
  395. }
  396. public static PersistenceSpecification<T> CheckComponentList<T, TListElement>(this PersistenceSpecification<T> spec,
  397. Expression<Func<T, IEnumerable<TListElement>>> expression,
  398. IEnumerable<TListElement> propertyValue,
  399. IEqualityComparer elementComparer,
  400. Action<T, IEnumerable<TListElement>> listSetter)
  401. {
  402. Accessor property = ReflectionHelper.GetAccessor(expression);
  403. var list = new List<T, TListElement>(property, propertyValue);
  404. list.ValueSetter = (target, propertyInfo, value) => listSetter(target, value);
  405. return spec.RegisterCheckedProperty(list, elementComparer);
  406. }
  407. [Obsolete("CheckEnumerable has been replaced with CheckList")]
  408. public static PersistenceSpecification<T> CheckEnumerable<T, TItem>(this PersistenceSpecification<T> spec,
  409. Expression<Func<T, IEnumerable<TItem>>> expression,
  410. Action<T, TItem> addAction,
  411. IEnumerable<TItem> itemsToAdd)
  412. {
  413. return spec.CheckList(expression, itemsToAdd, addAction);
  414. }
  415. private class FuncEqualityComparer<T> : EqualityComparer<T>
  416. {
  417. readonly IEnumerable<Func<T, object>> comparisons;
  418. public FuncEqualityComparer(IEnumerable<Func<T, object>> comparisons)
  419. {
  420. this.comparisons = comparisons;
  421. }
  422. public override bool Equals(T x, T y)
  423. {
  424. return comparisons.All(func => object.Equals(func(x), func(y)));
  425. }
  426. public override int GetHashCode(T obj)
  427. {
  428. throw new NotSupportedException();
  429. }
  430. }
  431. }
  432. }