使用SimpleInjector动态选择具有名称的具体对象 [英] Dynamically select a concrete object with a name using SimpleInjector
问题描述
如何使用Simple Injector DI容器注册 IShipper
接口的多种具体类型,并使用名称$ c $动态选择它们c>?
How can I use Simple Injector DI container to register multiple concrete types of IShipper
interface and dynamically select them using a name
?
如果我无法注册同一类型的多个实例,那么使用Simple Injector是否有其他方法?
If I can't register multiple instances of the same type, is there a different way to do with Simple Injector?
public Setup()
{
var container = new SimpleInjector.Container();
// TODO: Registration required for two different shippers
container.Register<UPS, IShipper>();
}
public interface IShipper
{
void Ship(Product product)
}
public class UPS : IShipper { ... }
public class FedEx : IShipper { ... }
public void Ship(String shipper, Product product)
{
// TODO: Retrieve the shipper by name
var shipper = container.GetInstance<IShipper>();
shipper.Ship(product);
}
Ship("FedEx", new Product());
推荐答案
有很多方法可以做到这一点,例如您可以:
There are many ways of doing this, for instance you could:
- 定义一个
IShipperFactory
,它允许检索IShipper
。 - 创建一个实现
IShipper
的代理并将其委托给真实的IShipper
的实现;如果Product
实体本身包含有关托运人的信息,则此方法有效。 - 创建要转发的'dispatcher
内部调用适当的 c
,而不会向客户端公开此hhhb的抽象。
- Define a
IShipperFactory
that allows retrieving aIShipper
. - Create a proxy that implements
IShipper
and delegates to the realIShipper
implementation; this works in case theProduct
entity itself contains information about the shipper. - Create a 'dispatcher
that forwards the call to the proper
IShipperinternally, without exposing this
IShipper` abstraction back to the client.
文档这里提供了有关如何创建相同抽象的多个注册的一些线索。
The documentation here gives some clues about how to create multiple registrations of the same abstraction.
以下是使用调度程序的示例:
Here's an example using a dispatcher:
public interface IShippingDispatcher
{
void Ship(string shipper, Product product);
}
public class ShippingDispatcher : IShippingDispatcher
{
private readonly Func<string, IShipper> factory;
public ShippingDispatcher(Func<string, IShipper> factory) { this.factory = factory; }
public void Ship(string shipper, Product product) => factory(shipper).Ship(product);
}
例如,可以使用以下设置:
As an example, you can have the following setup with this:
public Setup()
{
var container = new Container();
var shippers = new Dictionary<string, InstanceProducer<IShipper>>
{
{ "FedEx", Lifestyle.Transient.CreateProducer<IShipper, FedEx>(container) },
{ "UPS", Lifestyle.Transient.CreateProducer<IShipper, UPS>(container) },
};
container.RegisterSingleton<IShippingDispatcher>(
new ShippingDispatcher(shipper => shippers[shipper].GetInstance()));
}
这篇关于使用SimpleInjector动态选择具有名称的具体对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!