简体   繁体   中英

StructureMap - Register Generic Type

I have the following code:

public class Dispatcher : IDispatcher {
  public void Send(Order order) {
    var type = typeof(IOrderHandler<>).MakeGenericType(order.GetType());
    var handler = ObjectFactory.GetInstance(type);
  }
}

NOTE: I am trying to get the IOrderHandler where order in this case is: public class CoffeOrder : Order { }

My StructureMap configuration is the following:

ObjectFactory.Initialize(x => {
  x.For<IOrderHandler>().Use<OrderHandler>();
});

When I debug it I get the following error: {"StructureMap configuration failures:\\r\\nError: 104\\r\\nSource: Registry: StructureMap.Configuration.DSL.Registry, StructureMap, Version=2.6.4.0, ...

I tried other options but I always end up with a 104 error or a 202 error: "StructureMap Exception Code: 202\\nNo Default Instance defined for PluginFamily Proj.Test.Tests+IOrderHandler`1[[Proj.Test.Tests+CoffeOrder, Proj.Test, ...

NOTE: CoffeOrder is the type of the Order I am passing on my test.

My code for a Handler class and interface is the following:

public class CoffeHandler : OrderHandler<CoffeOrder> {
  public override void Handle(CoffeOrder order) {
    // Some Code
  } // CoffeHandler
} 

public interface IOrderHandler {
  void Handle(Order order);
} // IOrderHandler

public interface IOrderHandler<TOrder> : IOrderHandler where TOrder : Order {
  void Handle(TOrder order);
} // IOrderHandler

public abstract class OrderHandler : IOrderHandler {
  public abstract void Handle(Order order);
} // OrderHandler

public abstract class OrderHandler<TOrder> : OrderHandler, IOrderHandler<TOrder> where TOrder : Order {

  public override void Handle(Order order) {
    TOrder torder = (TOrder)order;
    Handle(torder);
  } // Handle

  public abstract void Handle(TOrder order);

} // OrderHandler

Could someone, please, help me out?

Thank You, Miguel

Note that you are failing right away at registration and not at resolution. Your registration says: "When a class of type IOrderHandler is requested, return a concrete instance of OrderHandler

Your OrderHandler is an abstract class, so StructureMap cannot create a concrete instance of it. If you register as below,

ObjectFactory.Initialize(
            x => x.For<IOrderHandler<CoffeOrder>>().Use<CoffeHandler>());

You are saying, "When a class of type IOrderHandler<CoffeOrder> is requested (which is what you are requesting in your example), return a concrete instance of CoffeHandler . That is aa valid mapping because it can instantiate a CoffeHandler .

While the above addressed your problem, I have a hunch you may be wanting StructureMap to do more of the leg work for you if you have lots of different implementations you want to register. If that is the case, you are in luck because StructureMap has support for Open Generics.

Then your resolution code will be like:

var handler = ObjectFactory.ForGenericType(typeof(IOrderHandler<>))
             .WithParameters(order.GetType())
             .GetInstanceAs<IOrderHandler>();

If you had a concrete generic implementation of IOrderHandler<> you could just register that. But since you do not and [as-per my hunch] you are not wanting to register every concrete instance, you will need to do a scan. How to do that is really a different question which I cannot answer without knowing what you want to scan. But you can see here for a blog post detailing Structure Map open generics which includes a samples covering scanning.

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