Structure Map - Collection of Dependencies in Cons

2019-07-06 21:10发布

I have the following code in my Registry:

        Scan(x =>
        {
            x.Assembly(Assembly.GetExecutingAssembly());
            x.AddAllTypesOf<IXmlExtractor>();
        });

This code adds all instances of IXmlExtractor in my assembly to the IoC container.

Now I want to use all found instances in my class, but I prefer to inject via constructor than to use ObjectFactory in a method. Hopefully code below illustrates what I want to do:

class Engine : IEngine
{
    private readonly ILog _logger;
    private readonly ICurveConfigRepository _configRepo;
    private readonly IDataExtractor _dataExtractor;

    public Engine(ILog logger, 
            ICurveConfigRepository configRepo, 
            IDataExtractor dataExtractor 
            /* SomeCollectionOfIXmlExtractors allExtractors */)
    {
        _logger = logger;
        _configRepo = configRepo;
        _dataExtractor = dataExtractor;
    }

    public void Run(string mode)
    {
        _logger.Info(string.Format("About to run retrieve config for '{0}' mode.", mode));

        var config = _configRepo.LoadConfig(mode);

        _logger.Info("Config retrieved, extracting data");
        var data = _dataExtractor.GetCurves(config);

        _logger.Info("Data extracted");

        //  Foreach IXmlExtractor instance, call .DoStuff(data) with it.
        //  I don't like using ObjectFactory here - see comment in constructor
        var extractors = ObjectFactory.GetAllInstances<IXmlExtractor>();

    }
}

Hopefully this is clear, please comment back if further explanation is required.

  • C#: 4.0
  • StructureMap: 2.5.4.0

Thanks,

Graeme

1条回答
Anthone
2楼-- · 2019-07-06 21:37

You have already correctly registered all instances with the container.

Scan(x =>
{
    x.Assembly(Assembly.GetExecutingAssembly());
    x.AddAllTypesOf<IXmlExtractor>();
});

All you need to do is declare an array variable and StructureMap will take care of the constructor injection automatically.

class Engine : IEngine
{
    private readonly ILog _logger;
    private readonly ICurveConfigRepository _configRepo;
    private readonly IDataExtractor _dataExtractor;
    private readonly IXmlExtractors[] _allExtractors;

    public Engine(ILog logger, 
            ICurveConfigRepository configRepo, 
            IDataExtractor dataExtractor 
            IXmlExtractors[] allExtractors)
    {
        _logger = logger;
        _configRepo = configRepo;
        _dataExtractor = dataExtractor;
        _allExtractors = allExtractors;
    }

    public void Run(string mode)
    {
        _logger.Info(string.Format("About to run retrieve config for '{0}' mode.", mode));

        var config = _configRepo.LoadConfig(mode);

        _logger.Info("Config retrieved, extracting data");
        var data = _dataExtractor.GetCurves(config);

        _logger.Info("Data extracted");

        // Use extractors...
        foreach (var extractor in _allExtractors)
        {
            extractor.DoStuff(data);
        }
    }
}
查看更多
登录 后发表回答