在 Simple Injector 中使用运行时数据获取实例

Get instances using runtime data in Simple Injector

我有一个基于数据库中的用户配置构建用户界面的应用程序。我创建了一个名为 IAction 的界面,如下所示;

public interface IAction
{
    ActionType ActionType { get; }
    bool CanExecute { get; }
    void Configure(ActionConfigDto config);
    void Execute();
}

AddItemAction 之类的实现如下所示;

public class AddItemAction : IAction
{
    public ActionType ActionType 
    {
        get { return ActionType.AddItem; }
    }

    // Rest of implementation
}

启动时,我遍历了来自数据库的 ActionConfigDto 集合。它们指定了操作的一些可配置参数以及我用来匹配相应操作的 ActionType。可能有多个具有相同 ActionType 的 ActionConfigDto,因此应为每个配置创建相应 Action 的多个实例。创建 IAction 实例后,应将配置传递给操作 Configure 方法。

我正在使用 Simple Injector 作为我的 DI 容器,但我还没有找到一个示例来说明如何使用我只在运行时知道的数据来实例化 Action 的实例。

我知道 Simple Injector 的编写方式是为了阻止不良做法,所以,我的方法是否完全错误,您将如何实现这一要求,或者有没有办法使用 Simple 实现这种配置注射器?

在进行更多搜索后,我找到了一些关于 resolving instances by key 的文档,并实现了一个手动注册每种类型的 ActionFactory。

public class ActionFactory : IActionFactory
{
    private readonly Container _container;
    private readonly Dictionary<string, InstanceProducer> _producers; 

    public ActionFactory(Container container)
    {
        _container = container;
        _producers = new Dictionary<string, InstanceProducer>(StringComparer.OrdinalIgnoreCase);
    }

    public IAction Create(ActionType type)
    {
        var action = _producers[type.ToString()].GetInstance();
        return (IAction) action;
    }

    public void Register(Type type, string name, Lifestyle lifestyle = null)
    {
        lifestyle = lifestyle ?? Lifestyle.Transient;
        var registration = lifestyle.CreateRegistration(typeof (IAction), type, _container);
        var producer = new InstanceProducer(typeof (IAction), registration);
        _producers.Add(name, producer);
    }
}

我配置工厂如下;

var registrations =
    from type in AssemblySource.Instance.GetExportedTypes()
    where typeof (IAction).IsAssignableFrom(type)
    where !typeof (ActionDecorator).IsAssignableFrom(type)
    where !type.IsAbstract
    select new {Name = type.Name, ImplementationType = type};

var factory = new ActionFactory(container);
foreach (var reg in registrations)
{
    factory.Register(reg.ImplementationType, reg.Name);
}

container.RegisterSingle<IActionFactory>(factory);

Simple Injector 有很棒的文档,在我发现 link.

之前,我没想过使用密钥来注册 Actions