简单的注射器追踪时间

时间:2015-05-08 14:34:14

标签: c# dependency-injection ioc-container simple-injector

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

我的意思是跟踪级别

由于

1 个答案:

答案 0 :(得分:5)

解决Simple Injector中的实例非常快,除非your constructors do too much,否则永远不会成为问题。

尽管如此,添加跟踪是微不足道的,可以按照以下方式完成(对于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);

RegisterResolveInterceptor方法可以拦截对GetInstanceGetAllInstances的直接调用。因此,已注册的委托将应用于最外层对象,但不应用于其依赖项。

如果您需要更细粒度的信息,例如创建特定依赖项所需的时间,您可以按如下方式挂钩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) { ... }
    }
}