• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Sholtee / injector / 2253

28 Dec 2023 07:59AM UTC coverage: 90.757% (+0.03%) from 90.723%
2253

push

appveyor

Sholtee
introduce required property support

2170 of 2391 relevant lines covered (90.76%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.72
/SRC/Injector/Private/ServiceEntries/ProducibleServiceEntry.cs
1
/********************************************************************************
2
* ProducibleServiceEntry.cs                                                     *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Diagnostics;
9
using System.Linq;
10
using System.Linq.Expressions;
11
using System.Reflection;
12

13
namespace Solti.Utils.DI.Internals
14
{
15
    using Interfaces;
16
    using Primitives;
17

18
    using static Interfaces.Properties.Resources;
19
    using static Properties.Resources;
20

21
    /// <summary>
22
    /// Reperesents the base class of producible servce entries.
23
    /// </summary>
24
    public abstract partial class ProducibleServiceEntry : AbstractServiceEntry
25
    {
26
        #region Private
27
        private readonly List<Expression<DecoratorDelegate>> FDecorators = new();
1✔
28

29
        private static Expression<FactoryDelegate>? GetFactory(Type type, Type implementation, object? explicitArgs, ServiceOptions? options)
30
        {
1✔
31
            if (!implementation.IsClass)
1✔
32
                throw new ArgumentException(NOT_A_CLASS, nameof(implementation));
×
33

34
            ConstructorInfo ctor = implementation.GetApplicableConstructor();  // validates the implementation even in case of a generic svc
1✔
35
            return !type.IsGenericTypeDefinition
1✔
36
                ? new ServiceActivator(options).ResolveFactory(ctor, explicitArgs)
1✔
37
                : null;
1✔
38
        }
1✔
39

40
        private ProducibleServiceEntry(Type type, object? key, Type? implementation, Expression<FactoryDelegate>? factory, object? explicitArgs, ServiceOptions? options) : base(type, key, implementation, factory, explicitArgs, options ?? ServiceOptions.Default)
×
41
        {
1✔
42
            if (Options!.SupportAspects)
1✔
43
            {
1✔
44
                //
45
                // Since aspects may target the implementation itself, they must be applied first
46
                //
47

48
                Debug.Assert(Decorators.Count is 0, "Aspects must be applied first");
1✔
49
                Features = ServiceEntryFeatures.SupportsAspects;
1✔
50
                if (Factory is not null)
1✔
51
                    this.ApplyAspects();
1✔
52
            }
1✔
53
        }
1✔
54
        #endregion
55

56
        #region Protected
57
        /// <summary>
58
        /// Creartes a new <see cref="ProducibleServiceEntry"/> instance.
59
        /// </summary>
60
        protected ProducibleServiceEntry(Type type, object? key, Expression<FactoryDelegate> factory, ServiceOptions? options) : this
×
61
        (
×
62
            type ?? throw new ArgumentNullException(nameof(type)),
×
63
            key,
×
64
            null,
×
65
            factory ?? throw new ArgumentNullException(nameof(factory)),
×
66
            null,
×
67
            options
×
68
        ) {}
1✔
69

70
        /// <summary>
71
        /// Creartes a new <see cref="ProducibleServiceEntry"/> instance.
72
        /// </summary>
73
        protected ProducibleServiceEntry(Type type, object? key, Type implementation, ServiceOptions? options) : this
×
74
        (
×
75
            type ?? throw new ArgumentNullException(nameof(type)),
×
76
            key,
×
77
            implementation ?? throw new ArgumentNullException(nameof(implementation)),
×
78
            GetFactory
×
79
            (
×
80
                type,
×
81
                implementation,
×
82
                null,
×
83
                options
×
84
            ),
×
85
            null,
×
86
            options
×
87
        ) {}
1✔
88

89
        /// <summary>
90
        /// Creartes a new <see cref="ProducibleServiceEntry"/> instance.
91
        /// </summary>
92
        protected ProducibleServiceEntry(Type type, object? key, Type implementation, object explicitArgs, ServiceOptions? options) : this
×
93
        (
×
94
            type ?? throw new ArgumentNullException(nameof(type)),
×
95
            key,
×
96
            implementation ?? throw new ArgumentNullException(nameof(implementation)),
×
97
            GetFactory
×
98
            (
×
99
                type,
×
100
                implementation,
×
101
                explicitArgs ?? throw new ArgumentNullException(nameof(explicitArgs)),
×
102
                options
×
103
            ),
×
104
            explicitArgs,
×
105
            options
×
106
        ) {}
1✔
107
        #endregion
108

109
        /// <inheritdoc/>
110
        public override void Build(IBuildContext context, IReadOnlyList<IFactoryVisitor> visitors)
111
        {
1✔
112
            if (context is null)
1✔
113
                throw new ArgumentNullException(nameof(context));
×
114

115
            if (visitors is null)
1✔
116
                throw new ArgumentNullException(nameof(visitors));
×
117

118
            if (Factory is null)
1✔
119
                throw new InvalidOperationException(NOT_PRODUCIBLE);
×
120

121
            //
122
            // Chain all the related delegates
123
            //
124

125
            Expression<CreateServiceDelegate> factoryExpr = (Expression<CreateServiceDelegate>) visitors.Aggregate<IFactoryVisitor, LambdaExpression>
1✔
126
            (
1✔
127
                Factory,
1✔
128
                (visited, visitor) => visitor.Visit(visited, this)
1✔
129
            );
1✔
130

131
            Debug.WriteLine($"Created factory: {Environment.NewLine}{factoryExpr.GetDebugView()}");
1✔
132
            FCreateInstance = context
1✔
133
                .Compiler
1✔
134
                .Register(factoryExpr);
1✔
135

136
            State = (State | ServiceEntryStates.Built) & ~ServiceEntryStates.Validated;
1✔
137
        }
1✔
138

139
        /// <inheritdoc/>
140
        public sealed override void UpdateState(ServiceEntryStates newState)
141
        {
1✔
142
            Debug.WriteLineIf(newState < State, $"Downgrading state of {this}");
1✔
143
            UpdateStateInternal(newState);
1✔
144
        }
1✔
145

146
        /// <inheritdoc/>
147
        public override ServiceEntryFeatures Features { get; }
1✔
148

149
        /// <inheritdoc/>
150
        public override void Decorate(Expression<DecoratorDelegate> decorator)
151
        {
1✔
152
            if (Factory is null)
1✔
153
                throw new NotSupportedException(DECORATING_NOT_SUPPORTED);
1✔
154

155
            FDecorators.Add(decorator ?? throw new ArgumentNullException(nameof(decorator)));
×
156
        }
1✔
157

158
        /// <summary>
159
        /// Bound decorators.
160
        /// </summary>
161
        public sealed override IReadOnlyList<Expression<DecoratorDelegate>> Decorators => FDecorators;
1✔
162
    }
163
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc