简体   繁体   中英

How to get instance of generic object using StructureMap with 2 different cases?

I have following interface

 public interface IBuilder<T>
 {
    T Create(string param);
 }

with many classes that implement the interface above. One of them is:

 public class ConcreteABuilder : IBuilder<ConcreteA>
 {
        public ConcreteA Create(string param)
        {
            return new ConcreteA();
        }
 }

I'm using StructureMap to register all classes that implement IBuilder<>

Scan(x =>
{
      x.TheCallingAssembly();
      x.AddAllTypesOf(typeof(IBuilder<>));
});    

Now, I have 2 cases

EDITED

I get the types(in both cases) in the form of System.Type

Case 1

At runtime I get any T type( System.Type ) (eg typeof(ConcreteA) ) and I need to get the matched builder instance. In this case it must return ConcreteABuilder instance.

Case 2

At runtime I get the type( System.Type ) of some implemented IBuilder(eg typeof(ConcreteABuilder) ) and I need to get the matched builder instance. In this case it must return ConcreteABuilder instance.

How using StructureMap's ObjectFactory to solve Case1 & Case2?

Thank you

Use this in StructureMap configuration

x.ConnectImplementationsToTypesClosing(typeof(IBuilder<>))

now to resolve generic type at runtime

Type openType = typeof(IBuilder<>);//generic open type
var type = openType.MakeGenericType(modelType);//modelType is your runtime type

var builder = StructureMap.ObjectFactory.Container.GetInstance(type);//should get your ConcreteABuilder 

I think what you're looking for is registering your types with:

x.ConnectImplementationsToTypesClosing(typeof(IBuilder<>))

Then asking the container for an IBuilder<ConcreteA> or a ConcreteABuilder will return a ConcreteABuilder ... now the problem is that since you don't know the type until runtime (selected by the user or something?), you can only use the non-generic version:

object someBuilder = ObjectFactory.GetInstance(thePassedInTypeAtRuntime);
... then use reflection to invoke the createMethod

or

dynamic someBuilder = (dynamic)ObjectFactory.GetInstance(thePassedInTypeAtRuntime);
....

and somewhere where you actually know that you're asking for a an IBuilder that can return ConcreteA

ConcreteA myA = someBuilder.Create(someParams);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM