我有一个应用程序,它根据数据库中的用户配置构建其用户界面。我创建了一个名为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。可能有多个ActionConfigDto具有相同的ActionType,因此应为每个配置创建相应Action的多个实例。一旦创建了IAction实例,就应该将配置传递给动作配置方法。
我使用Simple Injector作为我的DI容器,但我没有找到一个示例,说明如何使用我在运行时才知道的数据来实例化Action的实例。
我知道Simple Injector的编写方式是为了阻止糟糕的做法,所以我的方法是错的,你会如何实现这个要求,或者有没有办法用Simple Injector实现这种配置?
答案 0 :(得分:4)
在做了一些搜索之后,我在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有很好的文档,我没有想过使用密钥来注册动作,直到找到链接。