Search code examples
c#asp.net-mvcinversion-of-controlautofac

Convert Unity/StructureMap interface registration


I recently switched from Unity to Autofac and am having difficulty getting my MVC ModelMetadataFilters dependencies to convert. These filters are all tagged with the interface IModelMetadataFilter and then should be injected via contructor here:

public ExtensibleModelMetadataProvider(IModelMetadataFilter[] metadataFilters)
{
    _metadataFilters = metadataFilters;
}

I have tried the code below. The ExtensibleModelMetadataProvider is registered, but not the IModelMetadataFilter classes.

builder.RegisterType<ExtensibleModelMetadataProvider>()
       .As<ModelMetadataProvider>()
       .InstancePerLifetimeScope();

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
       .Where(t => t.IsAssignableFrom(typeof(IModelMetadataFilter)))
       .AsImplementedInterfaces()
       .InstancePerLifetimeScope();

My unity code was:

container.RegisterType<ModelMetadataProvider, ExtensibleModelMetadataProvider>();
container.RegisterTypes(
            AllClasses.FromLoadedAssemblies().Where(type => typeof(IModelMetadataFilter).IsAssignableFrom(type)),
            WithMappings.FromAllInterfaces,
            WithName.TypeName,
            WithLifetime.Transient);

I had converted this from Matt Honeycutt's code below (StructureMap):

For<ModelMetadataProvider>().Use<ExtensibleModelMetadataProvider>();

Scan(scan =>
{
    scan.TheCallingAssembly();
    scan.AddAllTypesOf<IModelMetadataFilter>();
});

Solution

  • It looks like your use of IsAssignableFrom is reversed.

    You should use either typeof(IModelMetadataFilter).IsAssignableFrom(t) or the Autofac-provided extension method t.IsAssignableTo<IModelMetadataFilter>() which is much more human readable.