コード例 #1
0
            public object Resolve(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
            {
                var typeToConstruct = GetTypeToConstruct(keyToResolve);

                var    pooledObjectKey = new RegistrationKey(typeToConstruct, keyToResolve.Name);
                object obj             = container.GetPooledObject(pooledObjectKey);

                if (obj == null)
                {
                    if (typeToConstruct.GetTypeInfo().IsInterface)
                    {
                        if (typeToConstruct.GetTypeInfo().IsGenericType&&
                            typeToConstruct.GetGenericTypeDefinition() == typeof(IEnumerable <>))
                        {
                            obj = container.GetType().GetMethod(nameof(container.ResolveAll)).MakeGenericMethod(typeToConstruct.GenericTypeArguments.First()).Invoke(container, new object[0]);
                        }
                        else
                        {
                            throw new ObjectContainerException("Interface cannot be resolved: " + keyToResolve,
                                                               resolutionPath.ToTypeList());
                        }
                    }
                    else
                    {
                        obj = container.CreateObject(typeToConstruct, resolutionPath, keyToResolve);

                        container.objectPool.TryAdd(pooledObjectKey, obj);
                    }
                }

                return(obj);
            }
コード例 #2
0
            protected override object ResolvePerContext(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
            {
                var typeToConstruct = GetTypeToConstruct(keyToResolve);

                var pooledObjectKey = new RegistrationKey(typeToConstruct, keyToResolve.Name);

                var result = ExecuteWithLock(syncRoot, () => container.GetPooledObject(pooledObjectKey), () =>
                {
                    if (typeToConstruct.IsInterface)
                    {
                        throw new ObjectContainerException("Interface cannot be resolved: " + keyToResolve,
                                                           resolutionPath.ToTypeList());
                    }

                    var obj = container.CreateObject(typeToConstruct, resolutionPath, keyToResolve);
                    container.objectPool.Add(pooledObjectKey, obj);
                    return(obj);
                }, resolutionPath);

                return(result);
            }
コード例 #3
0
        private object CreateObject(Type type, ResolutionList resolutionPath, RegistrationKey keyToResolve)
        {
            var ctors = type.GetConstructors();

            if (ctors.Length == 0)
            {
                ctors = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
            }

            Debug.Assert(ctors.Length > 0, "Class must have a constructor!");

            int maxParamCount      = ctors.Max(ctor => ctor.GetParameters().Length);
            var maxParamCountCtors = ctors.Where(ctor => ctor.GetParameters().Length == maxParamCount).ToArray();

            object obj;

            if (maxParamCountCtors.Length == 1)
            {
                ConstructorInfo ctor = maxParamCountCtors[0];
                if (resolutionPath.Contains(keyToResolve))
                {
                    throw new ObjectContainerException("Circular dependency found! " + type.FullName, resolutionPath.ToTypeList());
                }

                var args = ResolveArguments(ctor.GetParameters(), keyToResolve, resolutionPath.AddToEnd(keyToResolve, type));
                obj = ctor.Invoke(args);
            }
            else
            {
                throw new ObjectContainerException("Multiple public constructors with same maximum parameter count are not supported! " + type.FullName, resolutionPath.ToTypeList());
            }

            OnObjectCreated(obj);

            return(obj);
        }
コード例 #4
0
        private object ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath)
        {
            if (keyToResolve.Type.IsPrimitive || keyToResolve.Type == typeof(string) || keyToResolve.Type.IsValueType)
            {
                throw new ObjectContainerException("Primitive types or structs cannot be resolved: " + keyToResolve.Type.FullName, resolutionPath.ToTypeList());
            }

            var registrationResult         = GetRegistrationResult(keyToResolve);
            var isImplicitTypeRegistration = registrationResult == null;
            var registrationToUse          = registrationResult ??
                                             new KeyValuePair <ObjectContainer, IRegistration>(this, new TypeRegistration(keyToResolve.Type));

            var resolutionPathForResolve = registrationToUse.Key == this ?
                                           resolutionPath : new ResolutionList();
            var result = registrationToUse.Value.Resolve(registrationToUse.Key, keyToResolve, resolutionPathForResolve);

            if (isImplicitTypeRegistration) // upon successful implicit registration, we register the rule, so that sub context can also get the same resolved value
            {
                AddRegistration(keyToResolve, registrationToUse.Value);
            }
            return(result);
        }
コード例 #5
0
            protected override object ResolvePerDependency(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
            {
                var typeToConstruct = GetTypeToConstruct(keyToResolve);

                if (typeToConstruct.IsInterface)
                {
                    throw new ObjectContainerException("Interface cannot be resolved: " + keyToResolve, resolutionPath.ToTypeList());
                }
                return(container.CreateObject(typeToConstruct, resolutionPath, keyToResolve));
            }
コード例 #6
0
            protected override object ResolvePerContext(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
            {
                var typeToConstruct = GetTypeToConstruct(keyToResolve);

                var    pooledObjectKey = new RegistrationKey(typeToConstruct, keyToResolve.Name);
                object obj             = container.GetPooledObject(pooledObjectKey);

                if (obj == null)
                {
                    if (typeToConstruct.IsInterface)
                    {
                        throw new ObjectContainerException("Interface cannot be resolved: " + keyToResolve, resolutionPath.ToTypeList());
                    }

                    obj = container.CreateObject(typeToConstruct, resolutionPath, keyToResolve);
                    container.objectPool.Add(pooledObjectKey, obj);
                }

                return(obj);
            }
コード例 #7
0
        private object InvokeFactoryDelegate(Delegate factoryDelegate, ResolutionList resolutionPath, RegistrationKey keyToResolve)
        {
            if (resolutionPath.Contains(keyToResolve))
            {
                throw new ObjectContainerException("Circular dependency found! " + factoryDelegate.ToString(), resolutionPath.ToTypeList());
            }

            var args = ResolveArguments(factoryDelegate.Method.GetParameters(), keyToResolve, resolutionPath.AddToEnd(keyToResolve, null));

            return(factoryDelegate.DynamicInvoke(args));
        }
コード例 #8
0
            protected static object ExecuteWithLock(object lockObject, Func <object> getter, Func <object> factory, ResolutionList resolutionPath)
            {
                var obj = getter();

                if (obj != null)
                {
                    return(obj);
                }

                if (ObjectContainer.DisableThreadSafeResolution)
                {
                    return(factory());
                }

                if (Monitor.TryEnter(lockObject, ConcurrentObjectResolutionTimeout))
                {
                    try
                    {
                        obj = getter();

                        if (obj != null)
                        {
                            return(obj);
                        }

                        obj = factory();
                        return(obj);
                    }
                    finally
                    {
                        Monitor.Exit(lockObject);
                    }
                }

                throw new ObjectContainerException("Concurrent object resolution timeout (potential circular dependency).", resolutionPath.ToTypeList());
            }
コード例 #9
0
        private object ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath)
        {
            if (keyToResolve.Type.IsPrimitive || keyToResolve.Type == typeof(string) || keyToResolve.Type.IsValueType)
            {
                throw new ObjectContainerException("Primitive types or structs cannot be resolved: " + keyToResolve.Type.FullName, resolutionPath.ToTypeList());
            }

            var registrationResult = GetRegistrationResult(keyToResolve);

            var registrationToUse = registrationResult ??
                                    new KeyValuePair <ObjectContainer, IRegistration>(this, EnsureImplicitRegistration(keyToResolve));

            var resolutionPathForResolve = registrationToUse.Key == this ?
                                           resolutionPath : new ResolutionList();
            var result = registrationToUse.Value.Resolve(registrationToUse.Key, keyToResolve, resolutionPathForResolve);

            return(result);
        }