Search code examples
c#.netstructuremapconstructor-injectionstructuremap3

Structuremap 3 constructor that accepts list of all registered types/instances


I have an object which expects an IEnumerable<IPluginType> as a parameter to it's constructor. I also have a line in my container configuration which adds all implementers of IPluginType:

x.Scan(s =>
{
    ...

    s.AddAllTypesOf<IPluginType>();
});

I've confirmed via container.WhatDoIHave() that the expected implementers are registered, but the IEnumerable is not being populated.

I guess I'm being a little optimistic thinking that Structuremap will know what I mean, how can I tell it?


Solution

  • If the IPluginTypes are definitely registered in the Container as you say, StructureMap does resolve it correctly and pass one of each registered type into the IEnumerable. As you found, you need to use interfaces, not abstract types.

    Here is a complete working example (or as a dotnetfiddle):

    using System;
    using System.Collections.Generic;
    using StructureMap;
    
    namespace StructureMapTest
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var container = new Container();
                container.Configure(x =>
                {
                    x.Scan(s =>
                    {
                        s.AssemblyContainingType<IPluginType>();
                        s.AddAllTypesOf<IPluginType>();
                    });
    
                    x.For<IMyType>().Use<MyType>();
                });
    
                var myType = container.GetInstance<IMyType>();
                myType.PrintPlugins();
            }
        }
    
        public interface IMyType
        {
            void PrintPlugins();
        }
    
        public class MyType : IMyType
        {
            private readonly IEnumerable<IPluginType> plugins;
    
            public MyType(IEnumerable<IPluginType> plugins)
            {
                this.plugins = plugins;
            }
    
            public void PrintPlugins()
            {
                foreach (var item in plugins)
                {
                    item.DoSomething();
                }
            }
        }
    
        public interface IPluginType
        {
            void DoSomething();
        }
    
        public class Plugin1 : IPluginType
        {
            public void DoSomething()
            {
                Console.WriteLine("Plugin1");
            }
        }
    
        public class Plugin2 : IPluginType
        {
            public void DoSomething()
            {
                Console.WriteLine("Plugin2");
            }
        }
    }