public InstanceProduct Produce() { IMethodProduct?predicateMethod = null; if (_bindingExtender.BindingContainer.IsConditional) { predicateMethod = MethodProductFactory.Create( $"CheckPredicate_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_typeInfoProvider.Bool()), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}({GN.IResolutionTarget} resolutionTarget) {{ global::System.Func<{GN.IResolutionTarget}, bool> predicate = {_bindingExtender.BindingContainer.WhenArgumentClause} ; var result = predicate(resolutionTarget); return result; }} "); } var retrieveObjectMethod = MethodProductFactory.Create( $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_bindingExtender.BindingContainer.BindToType), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}( {GN.IResolutionTarget} resolutionTarget ) {{ return {_bindingExtender.BindingContainer.ConstantSyntax!.GetText()}; }} "); var funcMethod = MethodProductFactory.Create( $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}{DpdtArgumentWrapperTypeEnum.Func.GetPostfix()}", new TypeMethodResult(_typeInfoProvider.Func(_bindingExtender.BindingContainer.BindToType)), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}( {GN.IResolutionTarget} resolutionTarget ) {{ return () => {retrieveObjectMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}(resolutionTarget); }} "); var product = new InstanceProduct( _bindingExtender, predicateMethod, retrieveObjectMethod, funcMethod, null, null ); return(product); }
private IMethodProduct CreateGetAllMethod( IReadOnlyList <InstanceProduct> filteredInstanceProducts, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var stableSuffix = GetStableSuffix(filteredInstanceProducts); string nonExplicitMethodName = $"GetAll_{wrapperSymbol.GetSpecialName()}_{stableSuffix}" ; var returnType = _typeInfoProvider .GetTypeByMetadataName("System.Collections.Generic.List`1") ! .Construct(wrapperSymbol) ; var getAllMethodProduct = MethodProductFactory.Create( nonExplicitMethodName, new TypeMethodResult(returnType), (methodName, returnType) => { var methodBody = $@"private {returnType} {methodName}({GN.IResolutionRequest} resolutionRequest) {{ resolutionRequest = resolutionRequest ?? new {GN.ResolutionRequest}<{ClusterBindings.ClusterType.ToGlobalDisplayString()}, {wrapperSymbol.ToGlobalDisplayString()}>(true); var result = new global::System.Collections.Generic.List<{wrapperSymbol.ToGlobalDisplayString()}>(); "; foreach (var instanceProduct in filteredInstanceProducts) { var modifiedContext = $"target_{instanceProduct.BindingExtender.BindingContainer.GetStableSuffix()}"; if (!(instanceProduct.PredicateMethod is null) || instanceProduct.BindingExtender.NeedToProcessResolutionContext) { methodBody += $@" var {modifiedContext} = new {GN.ResolutionTarget}<{ClusterBindings.ClusterType.ToGlobalDisplayString()}, {instanceProduct.BindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()}>( resolutionRequest ); "; } if (!(instanceProduct.PredicateMethod is null)) { //with predicate (itself is conditional!) methodBody += $@"//predicate method is same for all wrappers, so we does no need for a wrapper-postfix (like _Func) if({instanceProduct.PredicateMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}({modifiedContext})) {{ result.Add( {instanceProduct.FactoryObjectMethod.GetWrappedMethodName(wrapperType)}({modifiedContext}) ); }} "; }
private IMethodProduct CreateExplicitMethod( string explicitMethodName, IMethodProduct nonExplicitMethod, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var explicitMethodProduct = MethodProductFactory.Create( explicitMethodName, nonExplicitMethod.MethodResult, (methodName, returnType) => $@"{returnType} {GN.IResolution}<{wrapperSymbol.ToGlobalDisplayString()}>.{methodName}({GN.IResolutionRequest} resolutionRequest) {{ return {nonExplicitMethod.MethodName}(resolutionRequest); }} " ); return(explicitMethodProduct); }
public IMethodProduct GetMethodProduct( IMethodSymbol method ) { if (method is null) { throw new ArgumentNullException(nameof(method)); } var extractor = new MethodArgumentExtractor(); var constructorArguments = extractor.GetMethodArguments(method); var returnModifier = method.ReturnsVoid ? string.Empty : "return" ; var refModifier = (method.ReturnsByRef || method.ReturnsByRefReadonly) ? "ref" : string.Empty ; var result = MethodProductFactory.Create( method, constructorArguments, (methodName, h) => { return($@"public {h} {{ {returnModifier} {refModifier} _payload.{methodName}({constructorArguments.Join(ca => ca.GetUsageSyntax(), ",")}); }} "); } ); return(result); }
private ResolutionProduct CreateResolutionProduct( IReadOnlyList <InstanceProduct> filteredInstanceProducts, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var interfaceProduct = new NamedGeneric1Interface( GN.IResolution, wrapperSymbol ); var interfaceFastProduct = new NamedGeneric1Interface( GN.IResolutionFast, wrapperSymbol ); #region get var getMethodProduct = CreateGetMethod( filteredInstanceProducts, wrapperType, wrapperSymbol ); var getExplicitMethodProduct = CreateExplicitMethod( "Get", getMethodProduct, wrapperType, wrapperSymbol ); var canBeImplicitelyCastedToObject = wrapperSymbol.IsReferenceType; var nonGenericGetProduct = new CreateTupleProduct( new TypeTypePair ( _typeInfoProvider.SystemType(), wrapperSymbol ), new TypeStringPair ( _typeInfoProvider.Func( _typeInfoProvider.GetTypeByMetadataName(typeof(IResolutionRequest).FullName !) !, _typeInfoProvider.Object() ! ), canBeImplicitelyCastedToObject ? getMethodProduct.MethodName : $"(r) => {getMethodProduct.MethodName}(r)" ) ); #endregion #region get all var getAllMethodProduct = CreateGetAllMethod( filteredInstanceProducts, wrapperType, wrapperSymbol ); var getAllExplicitMethodProduct = CreateExplicitMethod( "GetAll", getAllMethodProduct, wrapperType, wrapperSymbol ); var nonGenericGetAllProduct = new CreateTupleProduct( new TypeTypePair ( _typeInfoProvider.SystemType(), wrapperSymbol ), new TypeStringPair ( _typeInfoProvider.Func( _typeInfoProvider.GetTypeByMetadataName(typeof(IResolutionRequest).FullName !) !, _typeInfoProvider.Object() ! ), canBeImplicitelyCastedToObject ? getAllMethodProduct.MethodName : $"(r) => {getAllMethodProduct.MethodName}(r)" ) ); #endregion #region get fast var getFastMethodProduct = MethodProductFactory.Create( nameof(IResolutionFast <object> .GetFast), new TypeMethodResult(wrapperSymbol), (methodName, returnType) => { return($@" {GN.AggressiveInlining} public {returnType} {methodName}({returnType} unused) {{ return {getMethodProduct.MethodName}( null ); }} "); } ); #endregion var resolutionProduct = new ResolutionProduct( interfaceProduct, interfaceFastProduct, getMethodProduct, getExplicitMethodProduct, nonGenericGetProduct, getAllMethodProduct, getAllExplicitMethodProduct, nonGenericGetAllProduct, getFastMethodProduct ); return(resolutionProduct); }
public InstanceProduct Produce() { var constructorArgumentProducers = _bindingExtender.BindingContainer.ConstructorArguments.ConvertToProducers( _clusterBindings, _bindingExtender ); var(caps, utps) = constructorArgumentProducers.Produce(); IMethodProduct?predicateMethod = null; if (_bindingExtender.BindingContainer.IsConditional) { predicateMethod = MethodProductFactory.Create( $"CheckPredicate_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_typeInfoProvider.Bool()), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}({GN.IResolutionTarget} resolutionTarget) {{ global::System.Func<{GN.IResolutionTarget}, bool> predicate = {_bindingExtender.BindingContainer.WhenArgumentClause} ; var result = predicate(resolutionTarget); return result; }} "); } var retrieveObjectMethod = MethodProductFactory.Create( $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_bindingExtender.BindingContainer.BindToType), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}( {GN.IResolutionTarget} resolutionTarget ) {{ return new {_bindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()}( {caps.Join(p => p.ResolveConstructorArgumentClause, ",")} ); }} "); var funcMethod = MethodProductFactory.Create( $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}{DpdtArgumentWrapperTypeEnum.Func.GetPostfix()}", new TypeMethodResult(_typeInfoProvider.Func(_bindingExtender.BindingContainer.BindToType)), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}( {GN.IResolutionTarget} resolutionTarget ) {{ return () => {retrieveObjectMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}(resolutionTarget); }} "); var product = new InstanceProduct( _bindingExtender, predicateMethod, retrieveObjectMethod, funcMethod, null, utps ); return(product); }
public InstanceProduct Produce() { var constructorArgumentProducers = _bindingExtender.BindingContainer.ConstructorArguments.ConvertToProducers( _clusterBindings, _bindingExtender ); var(caps, utps) = constructorArgumentProducers.Produce(); IMethodProduct?predicateMethod = null; if (_bindingExtender.BindingContainer.IsConditional) { predicateMethod = MethodProductFactory.Create( $"CheckPredicate_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_typeInfoProvider.Bool()), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}({GN.IResolutionTarget} resolutionTarget) {{ global::System.Func<{GN.IResolutionTarget}, bool> predicate = {_bindingExtender.BindingContainer.WhenArgumentClause} ; var result = predicate(resolutionTarget); return result; }} "); } var singletonInstanceName = $"_singletonInstance__{_bindingExtender.BindingContainer.BindToType.Name}__{_bindingExtender.BindingContainer.GetStableSuffix()}"; var lockerName = $"_locker_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}"; var retrieveObjectMethod = MethodProductFactory.Create( $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_bindingExtender.BindingContainer.BindToType), (methodName, returnType) => $@" private volatile {_bindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()} {singletonInstanceName} = null; private readonly global::System.Object {lockerName} = new global::System.Object(); {GN.AggressiveInlining} private {returnType} {methodName}( {GN.IResolutionTarget} resolutionTarget ) {{ if({singletonInstanceName} is null) {{ lock({lockerName}) {{ if({singletonInstanceName} is null) {{ {singletonInstanceName} = new {_bindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()}( {caps.Join(p => p.ResolveConstructorArgumentClause, ",")} ); }} }} }} return {singletonInstanceName}; }} "); var funcMethod = MethodProductFactory.Create( $"GetInstance_{ _bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}{DpdtArgumentWrapperTypeEnum.Func.GetPostfix()}", new TypeMethodResult(_typeInfoProvider.Func(_bindingExtender.BindingContainer.BindToType)), (methodName, returnType) => $@" {GN.AggressiveInlining} private {returnType} {methodName}( {GN.IResolutionTarget} resolutionTarget ) {{ return () => {retrieveObjectMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}(resolutionTarget); }} "); var disposeMethodInvoke = MethodProductFactory.Create( $"DisposeInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}", new TypeMethodResult(_typeInfoProvider.Void()), (methodName, returnType) => $@" private {returnType} {methodName}( ) {{ if({singletonInstanceName} is {GN.IDisposable} d) {{ d.{nameof(IDisposable.Dispose)}(); }} }} "); var product = new InstanceProduct( _bindingExtender, predicateMethod, retrieveObjectMethod, funcMethod, disposeMethodInvoke, utps ); return(product); }