コード例 #1
0
            private void AnalyzeInvocation(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax node, IMethodSymbol method)
            {
                var invocationNodes = node.Parent.Ancestors().OfType <InvocationExpressionSyntax>().ToArray();

                var invocations = (from i in invocationNodes
                                   let sym = context.SemanticModel.GetSymbolInfo(i)
                                             where sym.Symbol?.Kind == SymbolKind.Method
                                             let methodSymbol = (IMethodSymbol)sym.Symbol
                                                                select new StructureMapConfigurationInvocation(methodSymbol, i)).ToArray();

                ITypeSymbol           plugin;
                StructureMapLifecycle lifecycle = null;

                if (method.Name.Equals("ForSingletonOf"))
                {
                    lifecycle = StructureMapLifecycle.Singleton;
                }

                ITypeSymbol PluginFromArgument(ExpressionSyntax expr)
                {
                    // ReSharper disable once ConvertIfStatementToSwitchStatement
                    if (expr is TypeOfExpressionSyntax toe)
                    {
                        var typeInfo = context.SemanticModel.GetTypeInfo(toe.Type);
                        return(typeInfo.Type);
                    }

                    // ReSharper disable once InvertIf
                    if (expr is InvocationExpressionSyntax ies && ies.Expression is MemberAccessExpressionSyntax mes)
                    {
                        var sym = context.SemanticModel.GetSymbolInfo(ies);
                        // ReSharper disable once InvertIf
                        if (sym.Symbol != null && sym.Symbol.Name.Equals("GetType"))
                        {
                            var typeInfo = context.SemanticModel.GetTypeInfo(mes.Expression);
                            return(typeInfo.Type);
                        }
                    }

                    if (expr is IdentifierNameSyntax ins)
                    {
                        var sym = context.SemanticModel.GetTypeInfo(ins);
                        return(sym.Type);
                    }

                    return(null);
                }

                StructureMapLifecycle LifecycleFromArgument(ExpressionSyntax expr)
                {
                    var lifecycleType = context.SemanticModel.GetTypeInfo(expr).Type;

                    return(LifecycleMap[lifecycleType.ToDisplayString()]);
                }

                if (method.IsGenericMethod)
                {
                    plugin = method.TypeArguments[0];

                    if (node.ArgumentList.Arguments.Count > 0)
                    {
                        lifecycle = LifecycleFromArgument(node.ArgumentList.Arguments[0].Expression);
                    }
                }
                else
                {
                    var expr = node.ArgumentList.Arguments[0].Expression;

                    plugin = PluginFromArgument(expr);

                    if (node.ArgumentList.Arguments.Count > 1)
                    {
                        lifecycle = LifecycleFromArgument(node.ArgumentList.Arguments[1].Expression);
                    }
                }

                if (plugin == null)
                {
                    return;
                }

                StructureMapLifecycle FromInvocation(StructureMapConfigurationInvocation i)
                {
                    switch (i.MethodSymbol.Name)
                    {
                    case "LifecycleIs":
                    {
                        if (i.MethodSymbol.IsGenericMethod)
                        {
                            var lifecycleType = i.MethodSymbol.TypeArguments[0];
                            return(LifecycleMap[lifecycleType.ToDisplayString()]);
                        }
                        else
                        {
                            var lifecycleType = context.SemanticModel.GetTypeInfo(i.Invocation.ArgumentList.Arguments[0].Expression).Type;
                            return(LifecycleMap[lifecycleType.ToDisplayString()]);
                        }
                    }

                    case "Singleton":
                    {
                        return(StructureMapLifecycle.Singleton);
                    }

                    case "AlwaysUnique":
                    {
                        return(StructureMapLifecycle.Unique);
                    }

                    case "Transient":
                    {
                        return(StructureMapLifecycle.Transient);
                    }

                    default:
                    {
                        return(null);
                    }
                    }
                }

                lifecycle = lifecycle ?? invocations.Select(FromInvocation).FirstOrDefault(x => x != null) ?? StructureMapLifecycle.TransientImplicit;

                var concretesPluggedBy = new[] { "Use", "Add" };

                var concretePluginInvocation =
                    invocations.FirstOrDefault(x => concretesPluggedBy.Any(s => s.Equals(x.MethodSymbol.Name, StringComparison.Ordinal)));

                var concretePlugin = plugin;

                ITypeSymbol ConcretePluginFrom(StructureMapConfigurationInvocation invocation)
                {
                    if (invocation.MethodSymbol.IsGenericMethod)
                    {
                        return(invocation.MethodSymbol.TypeArguments[0]);
                    }

                    var expr           = invocation.Invocation.ArgumentList.Arguments[invocation.Invocation.ArgumentList.Arguments.Count - 1].Expression;
                    var pluginToReturn = PluginFromArgument(expr);

                    if (pluginToReturn == null)
                    {
                        if (expr is LambdaExpressionSyntax les)
                        {
                            var bodyType = context.SemanticModel.GetTypeInfo(les.Body);
                            return(bodyType.Type ?? (context.SemanticModel.GetSymbolInfo(expr).Symbol as IMethodSymbol)?.ReturnType);
                        }
                    }

                    return(pluginToReturn);
                }

                if (concretePluginInvocation != null)
                {
                    concretePlugin = ConcretePluginFrom(concretePluginInvocation);
                }

                var assembly = context.Compilation.Assembly;

                var wiringCtx = new StructureMapWiringCtx(node, plugin, lifecycle, assembly, concretePlugin);

                host.wirings.Add(wiringCtx);
            }
コード例 #2
0
 private static void WriteLocations(StructureMapWiringCtx item)
 {
     Console.WriteLine($"\t\t{item.Invocation.GetLocation()}");
 }