C# 自动将调试器通过方法单步执行到特定行

C# 自动将调试器通过方法单步执行到特定行,c#,visual-studio,debugging,attributes,C#,Visual Studio,Debugging,Attributes,所以我设置了一个拦截器。但我不想让调试器为它操心——我希望它在使用_service.FooBar()上的“介入”时直接从MyController转到MyService 公共类MyController:Controller { 私有只读IMyService_服务; 公共MyController(IMyService srv)=>\u service=srv; public void FooBar()=>\u service.FooBar();//我希望调试器从此处“介入”。。。 } 公共类MySe

所以我设置了一个拦截器。但我不想让调试器为它操心——我希望它在使用_service.FooBar()上的“介入”时直接从MyController转到MyService

公共类MyController:Controller
{
私有只读IMyService_服务;
公共MyController(IMyService srv)=>\u service=srv;
public void FooBar()=>\u service.FooBar();//我希望调试器从此处“介入”。。。
}
公共类MyService:IMyService
{
公共图书馆
{
将新的NotImplementedException();/…抛出到此处
}
}
公共静态类NinjectWebCommon
{
...
私有静态无效注册表服务(IBindingRoot内核)
{
var servicepassembly=Assembly.GetAssembly(typeof(MyService));
Bind(x=>
{
x、 来自(serviceAssembly)
.SelectAllClasses().BindDefaultInterface()
.Configure(p=>p.InRequestScope().Intercept().With());
});
}
公共类数据库TransactionInterceptor:IInterceptor
{
专用只读IDbEngineu dbEngine;
公共数据库TransactionInterceptor(IDBEngine dbEngine)
{
_dbEngine=dbEngine;
}
公共无效拦截(IInvocation调用)
{
var shouldTerminate=!invocation.ContainsAttribute();
尝试
{
invocation.procedure();
如果(应该终止)
{
_dbEngine.Terminate();
}
}
抓住
{
_dbEngine.Terminate(true);
投掷;
}
}
}
内部静态类NinjectionLocationExtensions
{
内部静态bool ContainsAttribute(此IInvocation调用),其中T:Attribute
{
var-request=invocation.request;
var wasCalledFromInterface=request.Method.DeclaringType!=null;
返回wasCalledFromInterface
?接口请求包含属性(请求)
:ConcreteRequestContainsAttribute(请求);
}
...
私有静态MethodInfo GetDerivedMethod(类型derivedType,MethodInfo interfaceMethod)=>
derivedType.GetMethods()
.Single(derivedMethod=>derivedMethod.IsEqualForOverloadResolution(interfaceMethod));
}
我通过向DatabaseTransactionInterceptor类添加DebuggerStepThrough属性来管理部分成功,但它仍然进入NinjectInvocationExtensions.ContainsAttribute()。我尝试将该属性添加到NinjectInvocationExtensions,但调试器仍然进入GetDerivedMethod()

有什么方法可以实现我想要的吗?

感谢并帮助我实现了这个解决方案

我只是需要重构一点,以便确定“shouldTerminate”的逻辑在它自己的方法中,用[DebuggerStepperBoundary]标记该方法,确保它是调用之后调用的第一件事,确保shouldTerminate之后没有我想要的步骤,并确保调用是第一件调用的事情

以下代码完全按照预期工作:

[DebuggerStepThrough]
public class DatabaseTransactionInterceptor : IInterceptor
{
    private readonly IDBEngine _dbEngine;

    public DatabaseTransactionInterceptor(IDBEngine dbEngine) => _dbEngine = dbEngine;

    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();

            if (ShouldTerminate(invocation))
                _dbEngine.Terminate();
        }
        catch
        {
            _dbEngine.Terminate(true);

            throw;
        }
    }

    [DebuggerStepperBoundary]
    private static bool ShouldTerminate(IInvocation invocation) =>
        !invocation.ContainsAttribute<DoNotTerminateAttribute>();
}
[DebuggerStepThrough]
公共类数据库TransactionInterceptor:IInterceptor
{
专用只读IDbEngineu dbEngine;
公共数据库TransactionInterceptor(IDBEGINE dbEngine)=>\u dbEngine=dbEngine;
公共无效拦截(IInvocation调用)
{
尝试
{
invocation.procedure();
如果(应该终止(调用))
_dbEngine.Terminate();
}
抓住
{
_dbEngine.Terminate(true);
投掷;
}
}
[调试程序数据库]
私有静态bool应该终止(IInvocation调用)=>
!invocation.ContainsAttribute();
}

我假设添加
[DebuggerStepThrough]
GetDerivedMethod
不是您要寻找的答案吗?您的意思是不仅要阻止调试器进入
截取
,而且要
截取
使调试器跳过它调用的所有内容,即使调试器本来要进入的代码是called别处?我唯一能想到的是,您可以将它调用的所有代码复制到标有DebuggerStepThrough的内部代码中。@StriplingWarrior“我假设将[DebuggerStepThrough]添加到GetDerivedMethod不是您要寻找的答案?”是的,这也不起作用-出于某种原因,它没有停在那里。不知道为什么。此外,虽然我不是交易破坏者,但我更愿意避免更改NinjectInvocationExtensions。“你是说[…]如果它在其他地方被调用?”是的,没错。你说“出于某种原因它没有停在那里”是什么意思?看看这是否合适:@StriplingWarrior所以删除所有[DebuggerStepThrough],添加一个来拦截,并添加一个[DebuggerStepThrough,DebuggerStepBoundary]到一个新的私有bool ShouldTerminate(IInvocation调用)方法?我给它一个机会…不起作用,它在ctor中停止了。添加[DebuggerStepThrough]对于ctor…一个改进。它将我带到我创建的一个procedure()方法。添加[DebuggerStepThrough]到该方法…我想这就对了!明天我将进行更彻底的测试。谢谢你们的帮助。
[DebuggerStepThrough]
public class DatabaseTransactionInterceptor : IInterceptor
{
    private readonly IDBEngine _dbEngine;

    public DatabaseTransactionInterceptor(IDBEngine dbEngine) => _dbEngine = dbEngine;

    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();

            if (ShouldTerminate(invocation))
                _dbEngine.Terminate();
        }
        catch
        {
            _dbEngine.Terminate(true);

            throw;
        }
    }

    [DebuggerStepperBoundary]
    private static bool ShouldTerminate(IInvocation invocation) =>
        !invocation.ContainsAttribute<DoNotTerminateAttribute>();
}