简体   繁体   中英

Roslyn VisitExpressionStatement does not update expression

I am trying to refactor some code to use dependency injection. I would ike to change this:-

public Customer GetCustomer(int customerId)
{
    return DALFactory.Factory.GetDAL<ICustomerDAL>().GetCustomer(customerId);
}

to this:-

public Customer GetCustomer(int customerId)
{
    return this.customerDAL.GetCustomer(customerId);
}

My attempt looks like this:-

public class BllRewriter : CSharpSyntaxRewriter
{
    public override SyntaxNode VisitExpressionStatement(ExpressionStatementSyntax node)
    {
        if (node.ToString().StartsWith("DALFactory.Factory.GetDAL<"))
        {
            // code is "DALFactory.Factory.GetDAL<ICustomerDAL>().GetCustomer(customerId);"
            string code = node.ToString();

            // interfaceName is "ICustomerDAL"
            string interfaceName = GetInterfaceName(code);

            // propertyName is "customerDAL"
            string propertyName = interfaceName.Substring(1);
            propertyName = "this." + propertyName.Substring(0, 1).ToLowerInvariant() + propertyName.Substring(1);

            int closingBracketIndex = code.IndexOf(">");
            string expression = code.Substring(closingBracketIndex + 3);

            // "newLine" is "this.customerDAL.GetCustomer(customerId);"
            string newLine = $"{propertyName}{expression}";

            ExpressionSyntax newExpressionSyntax = SyntaxFactory.ParseExpression(newLine);

            ExpressionStatementSyntax newExpressionStatementSyntax = SyntaxFactory.ExpressionStatement(newExpressionSyntax);

            // node.ToString() is "this.customerDAL.GetCustomer(customerId);;"
            node = node.ReplaceNode(node, newExpressionStatementSyntax);
        }

        return base.VisitExpressionStatement(node);
    }

    private static string GetInterfaceName(string code)
    {
        string interfaceName = code.Substring("DALFactory.Factory.GetDAL<".Length);
        int closingBracketIndex = interfaceName.IndexOf('>');
        interfaceName = interfaceName.Substring(0, closingBracketIndex);
        return interfaceName;
    }
}

Stepping through the solution I see that it executes correctly and AFAICS it should update the code with the modified expression. But it doesn't. I can't work out why. Any ideas?

return DALFactory.Factory.GetDAL<ICustomerDAL>().GetCustomer(customerId); is ReturnStatement .

DALFactory.Factory.GetDAL<ICustomerDAL>().GetCustomer(customerId) is InvocationExpression .

try override VisitReturnStatement or VisitInvocationExpression return new node.

public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
    {
        if (node.ToString().StartsWith("DALFactory.Factory.GetDAL<"))
        {
            // ...
            return SyntaxFactory.ParseExpression($"{propertyName}{expression}");
        }

        return base.VisitExpressionStatement(node);
    }

You need to return new tree when using rewriter like this:

var bllRewriter = new BllRewriter();
var newRoot = bllRewriter.Visit(root);
var newCode = newRoot.GetText();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM