autofac / Autofac

An addictive .NET IoC container
https://autofac.org
MIT License
4.48k stars 836 forks source link

AttributedMetadataModule slows down service resolution considerably #1399

Closed xumix closed 11 months ago

xumix commented 11 months ago

Describe the Bug

It looks like AttributedMetadataModule.AttachToComponentRegistration is getting called for each resolution, therefore causing some unpleasant effects. I've attached screenshot of our application tracing and highlighted the offending lines (the time is cumulative). Our custom modules are also highlighted for comparison.

Steps to Reproduce

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
[MetadataAttribute]
public sealed class ServiceAsInterfacesAttribute : Attribute
{
    public int Order { get; set; }
}

//Register

builder.RegisterModule<AttributedMetadataModule>();

builder.RegisterAssemblyTypes(assembly)
    .Where(t => t.HasCustomAttribute<ServiceAsInterfacesAttribute>()
                && !t.IsInterface && !t.IsAbstract && !t.IsGenericTypeDefinition)
    .AsImplementedInterfaces()
    .WithMetadataFrom<ServiceAsInterfacesAttribute>()
    .InstancePerLifetimeScope();

//Resolve

GetService<Meta<ISaveChangesListener>[]>()
    .OrderBy(x => x.Metadata.ContainsKey("Order")
        ? x.Metadata["Order"]
        : int.MaxValue)
    .Select(x => x.Value)
    .ToArray();

Expected Behavior

Metadata is added once per registration, then used during resolve

Exception with Stack Trace

изображение

Dependency Versions

Autofac: 6.3.0

tillig commented 11 months ago

Attributed metadata does have a perf impact, which is why it's all very much opt-in / pay-for-play. In fact, it's so opt in that you didn't even file this in the right repo - Autofac.Extras.AtributeMetadata has its own repo and issues list.

If you don't want the perf hit, don't use attribute metadata.

If you want better perf, we'd love to see a PR in that repository to help optimize.