public object Resolve(TypeKey type) { if (_optimizationCallCache.ContainsKey(type)) return _optimizationCallCache[type](); _typesCallResolveStack = new HashSet<TypeKey>(); SetupPerRequest(type); _recorder.Start(); var newObj = ResolveType(type); var exp = _recorder.Result(); if (exp != null) { Func<object> method; if (_binder.IsSingleton(type)) method = () => (newObj); else method = (Func<object>)exp.Compile(); _optimizationCallCache.Add(type, method); } return newObj; }
private void SetupPerRequest(TypeKey type) { _requestObjectBag = new Dictionary<TypeKey, object>(); _perRequest = false; if (!_binder.IsConfigured(type)) return; var config = _binder.Configuration[type]; if (config.ActivationType == ActivationType.PerRequest || config.ActivationType == ActivationType.Singleton) _perRequest = true; }
private object ResolveType(TypeKey type) { var newObject = ResolveCustomHandler(type); if (newObject != null) return newObject; newObject = ResolvePerRequestObject(type); if (newObject != null) return newObject; newObject = _binder.IsConfigured(type) ? ResolveConfiguredType(type) : ResolveUnConfiguredType(type); ResolveCustomInitialization(type, newObject); AddPerRequestObject(type, newObject); return newObject; }
private object ResolveCustomHandler(TypeKey targetType) { if (_sigletonBag.ContainsKey(targetType)) return _sigletonBag[targetType]; var newObj = _binder.CustomResolve(targetType.Type); if (newObj.Value != null) { _recorder.CustomResolve(newObj.Key, newObj.Value, _binder, targetType.Type); ActivatePerRequest(); if (_binder.IsSingleton(targetType)) _sigletonBag.Add(targetType, newObj.Value); ResolveCustomInitialization(targetType, newObj.Value); } return newObj.Value; }
private void ResolveCustomInitialization(TypeKey targetType, object newObj) { var initialization = _binder.GetInitializeObjectWith(targetType); if (initialization != null) _recorder.InitializeObjectWith(initialization, newObj); }
private void AddPerRequestObject(TypeKey type, object newObject) { if (_perRequest) { _requestObjectBag.Add(type, newObject); } }
private object ResolveConfiguredType(TypeKey type) { object newObject = null; if (_typesCallResolveStack.Contains(type)) throw new CircularDependencyException(); _typesCallResolveStack.Add(type); var config = _binder.Configuration[type]; switch (config.ConstructorType) { case ConstructorType.NoArguments: newObject = _recorder.ActivatorCreateInstance(config.Target, _binder.IsSingleton(new TypeKey(config.Source))); break; case ConstructorType.Default: case ConstructorType.WithCustom: newObject = CreateObjectWithConstructor(config); break; default: throw new ArgumentOutOfRangeException(); } AddIfSingleton(newObject, config); _typesCallResolveStack.Remove(type); return newObject; }
private object ResolveUnConfiguredType(TypeKey type) { object newObject = null; //TODO: detect if exists multiple defaults if (type.Type.GetConstructors() .Where(c => c.GetCustomAttributes(false).Length >0 ).Where( c => c.GetCustomAttributes(false)[0] .GetType() .Equals(typeof(DefaultConstructorAttribute))) .Count() > 1) throw new MultipleDefaultConstructorAttributesException(); if (type.Type.GetConstructor(new Type[] { }) != null) { newObject = _recorder.ActivatorCreateInstance(type.Type, _binder.IsSingleton(type)); } if(type.Type.GetConstructors().Length == 0) throw new UnboundTypeException(); //TODO: change this var newConfig = new TypeConfiguration(type.Type, type.Type); newConfig.Constructor = type.Type.GetConstructors()[0]; newConfig.ConstructorType = ConstructorType.WithCustom; _binder.Configuration.Add(type, newConfig); newObject = ResolveConfiguredType(type); return newObject; }
private object ResolvePerRequestObject(TypeKey type) { if (_perRequest && _requestObjectBag.ContainsKey(type)) return _requestObjectBag[type]; return null; }
public bool Equals(TypeKey other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(other._type, _type) && Equals(other._attributeType, _attributeType); }