Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="Chinchilla Software Limited">
4 : // // Copyright Chinchilla Software Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Reflection;
11 : using cdmdotnet.Logging;
12 : using Cqrs.Configuration;
13 : using Cqrs.Domain.Exceptions;
14 :
15 : namespace Cqrs.Domain.Factories
16 : {
17 : /// <summary>
18 : /// A factory for creating instances of aggregates.
19 : /// </summary>
20 : public class AggregateFactory : IAggregateFactory
21 1 : {
22 : /// <summary>
23 : /// Gets or sets the <see cref="IDependencyResolver"/> used.
24 : /// </summary>
25 : protected IDependencyResolver DependencyResolver { get; private set; }
26 :
27 : /// <summary>
28 : /// Gets or sets the <see cref="ILogger"/> used.
29 : /// </summary>
30 : protected ILogger Logger { get; private set; }
31 :
32 : /// <summary>
33 : /// Instantiates a new instance of <see cref="AggregateFactory"/>.
34 : /// </summary>
35 1 : public AggregateFactory(IDependencyResolver dependencyResolver, ILogger logger)
36 : {
37 : DependencyResolver = dependencyResolver;
38 : Logger = logger;
39 : }
40 :
41 : /// <summary>
42 : /// Creates instance of <typeparamref name="TAggregate"/>.
43 : /// </summary>
44 : /// <typeparam name="TAggregate">The <see cref="Type"/> of the aggregate to create.</typeparam>
45 : /// <param name="rsn">The identifier of the aggregate to create an instance of if an existing aggregate.</param>
46 : /// <param name="tryDependencyResolutionFirst">Indicates the use of <see cref="IDependencyResolver"/> should be tried first.</param>
47 1 : public virtual TAggregate Create<TAggregate>(Guid? rsn = null, bool tryDependencyResolutionFirst = true)
48 : {
49 : return (TAggregate)Create(typeof(TAggregate), rsn, tryDependencyResolutionFirst);
50 : }
51 :
52 : /// <summary>
53 : /// Creates instance of type <paramref name="aggregateType"/>
54 : /// </summary>
55 : /// <param name="aggregateType">The <see cref="Type"/> of the aggregate to create.</param>
56 : /// <param name="rsn">The identifier of the aggregate to create an instance of if an existing aggregate.</param>
57 : /// <param name="tryDependencyResolutionFirst">Indicates the use of <see cref="IDependencyResolver"/> should be tried first.</param>
58 1 : public object Create(Type aggregateType, Guid? rsn = null, bool tryDependencyResolutionFirst = true)
59 : {
60 : if (tryDependencyResolutionFirst)
61 : {
62 : try
63 : {
64 : return DependencyResolver.Resolve(aggregateType);
65 : }
66 : catch
67 : {
68 : Logger.LogDebug(string.Format("Using the dependency resolver to create an instance of the aggregate typed '{0}' failed.", aggregateType.FullName), "Cqrs.Domain.Factories.AggregateFactory.Create");
69 : }
70 : }
71 :
72 : try
73 : {
74 : return Activator.CreateInstance(aggregateType, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, new object[] { DependencyResolver, Logger, rsn }, null);
75 : }
76 : catch (MissingMethodException exception)
77 : {
78 : Logger.LogDebug(string.Format("Looking for a private constructor with a dependency resolver and logger, to create an instance of the aggregate typed '{0}' failed.", aggregateType.FullName), "Cqrs.Domain.Factories.AggregateFactory.Create", exception);
79 : try
80 : {
81 : return Activator.CreateInstance(aggregateType, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, new object[] { DependencyResolver, Logger }, null);
82 : }
83 : catch (MissingMethodException exception2)
84 : {
85 : Logger.LogDebug(string.Format("Looking for a private constructor with a dependency resolver and logger, to create an instance of the aggregate typed '{0}' failed.", aggregateType.FullName), "Cqrs.Domain.Factories.AggregateFactory.Create", exception2);
86 : try
87 : {
88 : return Activator.CreateInstance(aggregateType, true);
89 : }
90 : catch (MissingMethodException)
91 : {
92 : if (!tryDependencyResolutionFirst)
93 : {
94 : try
95 : {
96 : return DependencyResolver.Resolve(aggregateType);
97 : }
98 : catch
99 : {
100 : Logger.LogDebug(string.Format("Using the dependency resolver to create an instance of the aggregate typed '{0}' failed.", aggregateType.FullName), "Cqrs.Domain.Factories.AggregateFactory.Create");
101 : }
102 : }
103 :
104 : throw new MissingParameterLessConstructorException(aggregateType);
105 : }
106 : }
107 : }
108 : }
109 : }
110 : }
|