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); }
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); }
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); }
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); }
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)); }
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); }
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)); }
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()); }
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); }