使用SimpleInjector动态选择具有名称的具体对象 [英] Dynamically select a concrete object with a name using SimpleInjector

查看:118
本文介绍了使用SimpleInjector动态选择具有名称的具体对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用Simple Injector DI容器注册 IShipper 接口的多种具体类型,并使用名称

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 a IShipper.
  • Create a proxy that implements IShipper and delegates to the real IShipper implementation; this works in case the Product entity itself contains information about the shipper.
  • Create a 'dispatcherthat forwards the call to the properIShipperinternally, without exposing thisIShipper` 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆