zcz527 / autofac

Automatically exported from code.google.com/p/autofac
Other
0 stars 0 forks source link

2.6.3.862 -> 3.0.2 : Adapter prevents retrieval of medata #427

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Reproduce steps:

1. Copy the source code below into an empty project file
2. In the package manager console, run the following to setup the environment:

install-package nunit
install-package autofac -Version 2.6.3.862

3. Run the unit test. It passes.
4. In the package manager console, run the following:

update-package autofac -Version 3.0.2

5. Run the unit test. It FAILS.

===== SOURCE CODE ======

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Autofac;
using Autofac.Builder;
using NUnit.Framework;

namespace ClassLibrary1
{
    public interface ICommand { }

    [ExportMetadata("Name", "C1")]
    public class C1 : ICommand { }

    [ExportMetadata("Name", "C2")]
    public class C2 : ICommand { }

    [ExportMetadata("Name", "C3")]
    public class C3 : ICommand { }

    public interface ICommandMetadata
    {
        string Name { get; }
    }

    [TestFixture]
    public class Test
    {
        [Test]
        public void Resolves_metadata_through_adapter()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<C1>().As<ICommand>().WithCommandMetadataFromAttributes();
            builder.RegisterType<C2>().As<ICommand>().WithCommandMetadataFromAttributes();
            builder.RegisterType<C3>().As<ICommand>().WithCommandMetadataFromAttributes();
            // yeah - probably a bit hackish ;)
            builder.RegisterAdapter<Lazy<ICommand, ICommandMetadata>, ICommandMetadata>(x => x.Metadata);
            var container = builder.Build();

            var metadata = container.Resolve<IEnumerable<ICommandMetadata>>().OrderBy(x => x.Name).ToList();
            Assert.That(metadata.Count, Is.EqualTo(3));
            Assert.That(metadata[0].Name, Is.EqualTo("C1"));
            Assert.That(metadata[1].Name, Is.EqualTo("C2"));
            Assert.That(metadata[2].Name, Is.EqualTo("C3"));
        }

    }

    public static class AutofacRegistrationExtensions
    {
        public static IRegistrationBuilder<T, IConcreteActivatorData, SingleRegistrationStyle>
            WithCommandMetadataFromAttributes<T>(
            this IRegistrationBuilder<T, IConcreteActivatorData, SingleRegistrationStyle> builder
            )
        {
            var exportedMetaData = GetExportedMetadataDict(typeof (T));
            return builder.WithMetadata<ICommandMetadata>(
                cfg => cfg.For(p => p.Name, (string) exportedMetaData["Name"])
                );
        }

        private static Dictionary<string, object> GetExportedMetadataDict(Type type)
        {
            return type.GetCustomAttributes(typeof (ExportMetadataAttribute), false)
                       .OfType<ExportMetadataAttribute>()
                       .Where(x => !x.IsMultiple)
                       .ToDictionary(x => x.Name, x => x.Value);
        }

    }

}

Original issue reported on code.google.com by kaleb.pe...@gmail.com on 17 Apr 2013 at 8:07

GoogleCodeExporter commented 8 years ago

Original comment by travis.illig on 18 Apr 2013 at 12:30

GoogleCodeExporter commented 8 years ago
I think this is an artifact of a breaking change described here:
http://alexmg.com/post/2012/11/01/Autofac-30-Beta-packages-available-on-NuGet.as
px

Switching the metadata object from an interface to a class should rectify the 
issue.

Original comment by travis.illig on 15 May 2013 at 11:47

GoogleCodeExporter commented 8 years ago
Confirmed this was a result of the interface -> class base metadata change via 
Twitter.

Original comment by alex.meyergleaves on 16 May 2013 at 12:19