public IInstanceFactory Handle(IResolverRequest request, Func<IResolverRequest, IInstanceFactory> nextHandler) { // pass if this is not a request for a Func<...> if (!request.RequestType.IsGenericType || request.RequestType.GetGenericTypeDefinition() != typeof(Func<>)) return nextHandler(request); var innerType = request.RequestType.GetGenericArguments()[0]; var factory = _pipeline.Resolve( new ResolverRequest( innerType, request.Context, request.Args) ); if (factory == null) return null; var funcType = typeof(Func<>).MakeGenericType(innerType); return new InstanceFactory( request.RequestType, Expression.Lambda( // Factory of... Expression.Lambda( // Factory of... Expression.Convert(factory.BuildExpression.Body, innerType)) //... (T)value )); }
public IInstanceFactory Handle(IResolverRequest request, Func<IResolverRequest, IInstanceFactory> nextHandler) { if (request == null) throw new ArgumentNullException("request"); if (nextHandler == null) throw new ArgumentNullException("nextHandler"); // If the component handler is last in the pipeline, this will return null. // However, it might not *always* be the last handler, so stick to the pattern // and pass to the next handler rather than returning null explicitly. if (request.RequestType.IsAbstract) return nextHandler(request); var ctors = request.RequestType .GetConstructors(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance); // this bad boy does the actual resolving... var ctorResolver = new ConstructorResolver(_pipeline); // ... we just order the results var factory = ctors .Select(ctor => ctorResolver.TryResolve(request, ctor)) .Where(f => f != null) // remove unresolvable ctors .OrderByDescending(f => f.Resolvable) // order by most parameters .OrderBy(f => f.Optional) // with the least optional parameters .FirstOrDefault(); return factory; }
public IInstanceFactory Handle(IResolverRequest request, Func<IResolverRequest, IInstanceFactory> nextBehaviour) { // If this is not a parameter request then pass var paramRequest = request as ParameterRequest; if (paramRequest == null) return nextBehaviour(request); // if Resolver Args are present and there's an arg that satisfies this parameter if (paramRequest.Args != null && paramRequest.Args.HasValueFor(paramRequest.Parameter.ParameterType, paramRequest.Parameter.Name)) { var value = request.Args.GetValueFor(paramRequest.Parameter.Name); return new InstanceFactory( request.RequestType, Expression.Lambda(Expression.Constant(value))); } // We couldn't resolve from ResolverArgs, so let the resolver pipeline run. // If there's a result, return it. var result = nextBehaviour(request); if (result != null) return result; // If not, our final option is to use the parameter default value if it has one return (paramRequest.Parameter.IsOptional) ? new InstanceFactory( request.RequestType, Expression.Lambda(Expression.Constant(paramRequest.Parameter.DefaultValue))) : null; }
public IInstanceFactory Handle(IResolverRequest request, Func<IResolverRequest,IInstanceFactory> nextHandler) { // this test handler handles requests for ITestComponent. // additionally, it only handles when there is a "Key" arg matching the _key value. if (request.RequestType != typeof(ITestComponent) || request.Args == null || !request.Args.HasValueFor(typeof(string),"Key") || (string)request.Args.GetValueFor("Key") != _key) return nextHandler(request); return new InstanceFactory(typeof(ITestComponent), ()=> _testable); }
public ConstructorFactory TryResolve(IResolverRequest request, ConstructorInfo ctor) { if (request == null) throw new ArgumentNullException("request"); var parameters = ctor.GetParameters(); // if this is the default ctor, then return a factory that calls the default ctor if (parameters.Length == 0) return new ConstructorFactory( request.RequestType, Expression.Lambda(Expression.New(ctor)), 0, 0); // for each parameter in the ctor, ask the resolver pipeline for a suitable factory. // Break if any parameters are unresolvable var factories = parameters .Select(p => _pipeline .Resolve(new ParameterRequest(p, request.Context, request.Args))) .TakeWhile(factory => factory != null) .ToArray(); // if the factory count doesn't match the parameter count, // then this ctor is unresolvable, so return null. if(factories.Length != parameters.Length) return null; // Count how many ctor parameters are optional because we can use this to settle a tie // between constructors. Where ctors with the same number of resolvable parameters are // available, then attempt to choose the ctor with the fewest optional parameters. var optional = parameters.Count(p => p.IsOptional); // Package up the parameter factories as a constructor factory return new ConstructorFactory( request.RequestType, Expression.Lambda( Expression.New( ctor, factories.Select(f => f.BuildExpression.Body))), parameters.Length, optional ); }
public IInstanceFactory Handle(IResolverRequest request, Func<IResolverRequest, IInstanceFactory> nextHandler) { if (request == null) throw new ArgumentNullException("request"); if (nextHandler == null) throw new ArgumentNullException("nextHandler"); // pass if this is not a request for a Lazy<...> if (!request.RequestType.IsGenericType || request.RequestType.GetGenericTypeDefinition() != typeof (Lazy<>)) return nextHandler(request); // attemp to get a factory for the T in Lazy<T> var innerType = request.RequestType.GetGenericArguments()[0]; var inner = _pipeline.Resolve(new ResolverRequest(innerType, request.Context, request.Args)); if (inner == null) return null; // find the ctor for Lazy<T> that takes a Func<T> var funcType = typeof (Func<>).MakeGenericType(innerType); var lazyType = typeof (Lazy<>).MakeGenericType(innerType); var ctor = lazyType.GetConstructor(new[] {funcType}); return new InstanceFactory( request.RequestType, MakeLazyExpression(inner.BuildExpression, innerType, ctor)); }
internal IInstanceFactory Handle(IResolverRequest request) { return _index == _handlers.Count ? null : _handlers[_index++].Handle(request, Handle); }
public IInstanceFactory Resolve(IResolverRequest request) { return new Iterator(_handlers).Handle(request); }