コード例 #1
0
        public void AddInstance <TService>(TService instance)
        {
            var instanceDelivery = new InstanceDelivery(LifetimeStatus.Singleton, instance?.GetType()); // don't check the constructor

            singletons.AddOrUpdate(instanceDelivery, instance, (key, existing) => instance);
            Add(typeof(TService), instanceDelivery);
        }
コード例 #2
0
 private void Add(Type type, InstanceDelivery instanceDelivery) =>
 types.AddOrUpdate(type,
                   t => new[] { instanceDelivery }.ToImmutableList(),
                   (t, l) =>
 {
     var b = l.ToBuilder();
     b.Add(instanceDelivery);
     return(b.ToImmutable());
 });
コード例 #3
0
        private object Resolve(Stack <Type> creating, InstanceDelivery instanceDelivery)
        {
            switch (instanceDelivery.Lifetime)
            {
            case LifetimeStatus.Singleton:
                return(singletons.GetOrAdd(instanceDelivery, d => Create(creating, d)));

            case LifetimeStatus.Transient:
                return(Create(creating, instanceDelivery));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #4
0
        private object Create(Stack <Type> creating, InstanceDelivery instanceDelivery)
        {
            if (creating.Contains(instanceDelivery.Type))
            {
                var allTypes = new[] { instanceDelivery.Type }.Concat(creating).ToArray();

                throw new ResolutionException("Circular reference when creating the following types:" +
                                              $"{Environment.NewLine}{string.Join(Environment.NewLine, allTypes.Select(t => t.FullName))}");
            }

            creating.Push(instanceDelivery.Type);
            try
            {
                var constructor     = constructors.GetOrAdd(instanceDelivery.Type, GetConstructor); //should always already be in.
                var parameterValues = new List <object>();
                foreach (var parameterInfo in constructor.GetParameters())
                {
                    var parameterValue = Resolve(creating, parameterInfo.ParameterType);
                    parameterValues.Add(parameterValue);
                }

                try
                {
                    var resolution = constructor.Invoke(parameterValues.ToArray());
                    return(resolution);
                }
                catch (Exception e)
                {
                    var allTypes = creating.ToArray(); //already got the type we're trying to create in the stack
                    throw new ResolutionException("Resolution failed when creating the following types:" +
                                                  $"{Environment.NewLine}{string.Join(Environment.NewLine, allTypes.Select(t => t.FullName))}",
                                                  e);
                }
            }
            finally
            {
                creating.Pop();
            }
        }