Я думаю, вы ошибаетесь. В основном потому, что ваш WidgetWrangler
ожидает и фабрику (IIndex<,>
фактически становится вашей фабрикой), и WidgetType.
Исключение состоит в том, что ваше перечисление WidgetType
не имеет регистрации по умолчанию в Autofac, и, вероятно, не должно. Autofac не может выяснить, какое значение передать конструктору, так как, я полагаю, вы пытаетесь использовать Autofac для восстановления вашего WidgetWrangler
.
Чтобы разрешить что-либо из Autofac, он должен содержать хотя бы один конструктор, который может быть полностью разрешен регистрациями Autofac, ИЛИ с явной передачей переменных в операцию разрешения (обратите внимание, этот метод является отражающим и чрезвычайно медленным).
Я предполагаю, что цель всего этого состоит в том, чтобы каким-то образом получить новый Подкласс Widget
, заданный где-то WidgetType
. Если это так, то ВСЕ, ЧТО ВАМ НУЖНО, это IIndex<,>
.
Везде, где вам нужно создавать новые виджеты, вы просто используете тип IIndex <,>. Это просто.
Если вам нужно выполнить еще одну операцию вместе с вашим экземпляром, вам следует обернуть IIndex в фабричный класс, который использует IIndex, а затем выполнить действия.
Например:
class Widget
{
// Stuff...
public virtual void Configure(XmlDocument xmlConfig)
{
// Config Stuff
}
}
interface IWidgetFactory
{
Widget Create(WidgetType type, XmlDocument config);
}
class WidgetFactory : IWidgetFactory
{
private readonly IIndex<WidgetType, Widget> _internalFactory;
public WidgetFactory(IIndex<WidgetType, Widget> internalFactory)
{
if (internalFactory == null) throw new ArgumentNullException("internalFactory");
_internalFactory = internalFactory;
}
public Widget Create(WidgetType type, XmlDocument config)
{
Widget instance = null;
if (!_internalFactory.TryGetValue(type, out instance))
{
throw new Exception("Unknown Widget Type: " + type.ToString);
}
instance.Configure(config);
return instance;
}
}
Вы можете просто использовать упакованную фабрику просто:
class SomethingThatNeedsWidgets
{
private readonly IWidgetFactory _factory;
public SomethingThatNeedsWidgets(IWidgetFactory factory)
{
if (factory == null) return new ArgumentNullException("factory");
_factory = factory;
}
public void DoSomething()
{
Widget myInstance = _factory.Create(WidgetType.Whizbang, XmlDocument.Load("config.xml"));
// etc...
}
}
Помните, если вам не нужно ничего делать, кроме как вернуть экземпляр Widget
, ваш IIndex<WidgetType, Widget>
- это фабрика сама по себе. (при условии, что все зарегистрированные Widget
подклассы зарегистрированы InstancePerDependency
. В противном случае это селектор экземпляра.