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

标签 c# architecture dependency-injection inversion-of-control 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 Injector 实现这种配置?

最佳答案

在进行更多搜索后,我找到了一些关于 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 有很好的文档,在找到该链接之前,我没想过使用 key 来注册 Actions。

关于c# - 在 Simple Injector 中使用运行时数据获取实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29044938/

相关文章:

c# - UDP网络与多个网络

ios - VALID_ARCHS = arm64 armv7 armv7s 不生成任何 armv7s

javascript - RequireJS - 依赖注入(inject)器或服务定位器

c# - EntityType 'DbGeography' 没有定义键

c# - 没有更新数据库的 EF6 种子

c# - 在 Windows 服务中更改计时器间隔

c# - 用于多个支付网关的最佳模式

architecture - MediaLibsDemo 缺少架构 x86_64

c# - 基于基本泛型类型调用正确的泛型接口(interface)实现

c# - MVVM Light 按键注册界面