简单的注射器追踪时间

adv*_*api 1 c# dependency-injection ioc-container simple-injector

有没有办法可以跟踪通过Simple Injector和Constructor的IoC解析实例需要多长时间?

我的意思是跟踪级别的东西

谢谢

Ste*_*ven 5

解决Simple Injector中的实例非常快,并且绝不应成为问题,除非你的构造函数做得太多.

尽管如此,添加跟踪是微不足道的,可以按如下方式完成(对于v2.8及更高版本):

container.Options.RegisterResolveInterceptor((context, producer) => {
        var watch = Stopwatch.StartNew();
        try {
            return producer();
        } finally {
            watch.Stop();
            if (watch.ElapsedMilliseconds > 50) {
                Console.WriteLine(
                    "Resolving {0} took {1} ms. Object graph: {2}",
                    context.Producer.ServiceType.Name,
                    watch.ElapsedMilliseconds,
                    context.Producer.VisualizeObjectGraph());
            }
        }
    },
    // Apply to every registration
    context => true);
Run Code Online (Sandbox Code Playgroud)

RegisterResolveInterceptor方法允许您拦截对GetInstance和的直接调用GetAllInstances.因此,已注册的委托将应用于最外层对象,但不应用于其依赖项.

如果您需要更细粒度的信息,例如创建特定依赖项所需的时间,您可以ExpressionBuilt按如下方式挂钩事件:

container.ExpressionBuilt += (s, e) =>
{
    MethodInfo monitorMethod = 
        this.GetType().GetMethod("Monitor").MakeGenericMethod(e.RegisteredServiceType);

    Delegate producer = Expression.Lambda(
        typeof(Func<>).MakeGenericType(e.RegisteredServiceType), e.Expression)
        .Compile();

    e.Expression = Expression.Call(monitorMethod, Expression.Constant(producer));
};


// Method somewhere else in the same class
public static T Monitor<T>(Func<T> producer) {
    var watch = Stopwatch.StartNew();
    try {
        T instance = producer();
        return instance;
    } finally {
        watch.Stop();
        if (watch.ElapsedMilliseconds > 50) { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)