Search code examples
c#abstract-classstructuremap

How to create an Instance of an Object in StructureMap Dynamically?


I have an Abstract Class called "ImportRunner".

I have an implementation of the class called "ScorecardRunner".

How can I at runtime get an instance of a class such as ScorecardRunner, when I am pulling the Object Type back as a String from an XML File and it could be any implementation of ImportRunner?

My current code is as follows.

var importer = container.GetInstance<ImportRunner>();

When I try to do something like below I get a compile error.

var importer = container.GetInstance<Type.GetType("Importer.ScorecardRunner")>();

Operator '<' cannot be applied to operands of type 'method group' and 'Type'

Thanks, Tom


Solution

  • Instead of spreading your logic for creating an instance based on runtime values and shoehorning it into your StructureMap's registry, a better approach would be to simply create a factory that's responsible for determining the correct runner instance and inject that.

    For example:

    public class XmlReader
    {
        public bool IsScoreCard { get; set; }
    }
    
    public abstract class ImportRunner
    {
    }
    
    public class ScorecardRunner : ImportRunner
    {
    }
    
    public class DefaultRunner : ImportRunner
    {
    }
    
    public class RunnerFactory
    {
        private readonly XmlReader _reader;
    
        public RunnerFactory(XmlReader reader)
        {
            _reader = reader;
        }
    
        public ImportRunner Resolve()
        {
            if (_reader.IsScoreCard)
                return new ScorecardRunner();
    
            return new DefaultRunner();
        }
    }
    

    Then configure it like so in your registry:

    this.For<ImportRunner>().Use(ctx => ctx.GetInstance<RunnerFactory>().Resolve());