编程语言
首页 > 编程语言> > c#-在Simple Injector中使用运行时数据获取实例

c#-在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,我用来匹配相应的Action.可能有多个具有相同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具有出色的文档,在找到该链接之前,我还没有考虑过使用键来注册操作.

标签:dependency-injection,architecture,c,inversion-of-control,simple-injector
来源: https://codeday.me/bug/20191028/1953420.html