private object ResolveCachedObjectWhileInsertingNewIfNotFound(Type interfaceType, object[] constructorData, Func <object, IResolverModule, Type, IResolver, object> moduleLogic, Func <IList <IResolverModule>, IList <IResolverModule> > moduleFilter) { if (!interfaceType.IsInterface) { throw new InvalidOperationException($"Incoming type \"{interfaceType.FullName}\" is not an Interface Type. Resolve only operates with Interfaces."); } Type classType = _mapper.MapInterfaceTypeToClassType(interfaceType); // If none found, create the first one if (!_repository.DoesObjectInterfaceAndClassExist(interfaceType, classType)) { if (constructorData != null && moduleLogic != null) { throw new InvalidOperationException($"Resolving should not be provided BOTH {nameof(constructorData)} and {nameof(moduleLogic)}."); } InsertNewObjectToCache(interfaceType, constructorData, moduleLogic, moduleFilter); } InstantiatedObject existingObject = _repository.ObjectCache.FirstOrDefault(obj => obj.ClassType == classType && obj.InterfaceType == interfaceType); if (existingObject == null || existingObject == default(InstantiatedObject)) { throw new NullReferenceException($"Failed to locate an object that instantiates type \"{interfaceType.Name}\" in the {nameof(InstantiatedObjectsRepository)}."); } return(existingObject.TheObject); }
private object InsertNewObjectToCache(Type interfaceType, object[] constructorData, Func <object, IResolverModule, Type, IResolver, object> moduleLogic, Func <IList <IResolverModule>, IList <IResolverModule> > moduleFilter) { constructorData = AddResolverToConstructorDataIfNeeded(interfaceType, constructorData); InstantiatedObject newObject = _mapper.MapInterfaceTypeToInstantiatedObject(interfaceType, constructorData, this, moduleLogic, moduleFilter); // If multiple not allowed and one already exists, throw if (!newObject.AllowMultiple && _repository.DoesObjectInterfaceAndClassExist(newObject.InterfaceType, newObject.ClassType)) { throw new InvalidOperationException($"Interface Type \"{newObject.InterfaceType.Name}\" mapped to Class Type \"{newObject.ClassType.FullName}\" is not set to support multiple instances and one was already resolved before."); } _repository.InsertObjectToCache(newObject); return(newObject.TheObject); }
/// <summary> /// Inserts the provided object to the cache of instantiated objects. /// </summary> /// <param name="objectToInsert">The object to insert into the cache.</param> public void InsertObjectToCache(InstantiatedObject objectToInsert) { if (objectToInsert == null) { throw new ArgumentNullException(nameof(objectToInsert), $"Cannot add a NULL {nameof(InstantiatedObject)} to the {nameof(InstantiatedObjectsRepository)}"); } objectToInsert.Validate(); // Replace the existing object if multiples not allowed and it exists already if (!objectToInsert.AllowMultiple && DoesObjectInterfaceAndClassExist(objectToInsert.InterfaceType, objectToInsert.ClassType)) { InstantiatedObject objectToRemove = ObjectCache.First(obj => obj.InterfaceType == objectToInsert.InterfaceType && obj.ClassType == objectToInsert.ClassType); if (objectToRemove == null) { throw new NullReferenceException($"The object mapped to \"{objectToInsert.InterfaceType.Name}\" is marked to not allow Multiple, was found in the Repository, but could not be retrieved."); } ObjectCache.Remove(objectToRemove); } ObjectCache.Add(objectToInsert); }
/// <summary> /// Checks if the provided InstantiatedObject exists in the object cache. /// </summary> /// <param name="objectToCheck">The InstantiatedObject to check for.</param> /// <returns>True if the provided InstantiatedObject exists in the cache and False otherwise.</returns> public bool DoesInstantiatedObjectExist(InstantiatedObject objectToCheck) { return(ObjectCache.Contains(objectToCheck)); }