Я создаю простое приложение с использованием MEF, чтобы лучше понять его, и у меня возникла проблема. Приложение представляет собой простой калькулятор, который позволяет создавать новые операции. Каждая операция - это класс, который экспортирует IOperation. Вот класс операции ADD:Контейнер для инъекций MEF
[Export(typeof(IOperation))]
internal class Add : IOperation
{
CompositionContainer _container;
public string Name
{
get { return "Add"; }
}
public string Symbol
{
get { return "+"; }
}
public IOperand Compute(params IOperand[] operands)
{
IOperand result = _container.GetExportedValue<IOperand>();
result.Value = operands.Sum(e => e.Value);
return result;
}
}
(. IOperand представляет собой интерфейс, который только выставляет двойной Причина этого в том, что в версии 2 вы можете иметь выражение типа «(2 + 2) * 4»)
Моя проблема, как вы можете видеть, заключается в том, что _container
имеет значение null, когда я ударил Compute
. Этот конкретный класс создается, когда контейнер составляет [ImportMany(typeof(IOperation))]
. Поэтому мой вопрос: есть ли способ сообщить контейнеру, который инвертирует контроль, чтобы передать ссылку на него на этот объект?
PS: Я не хотел бы делать _container
общественным достоянием.
edit1: Вот только реализация IOperand до сих пор:
[Export(typeof(IOperand))]
public class SimpleResult : IOperand
{
private double _value;
public double Value
{
get
{
return _value;
}
set
{
_value = value;
}
}
}
Это "Main", где композиция происходит:
public class Calculator
{
[ImportMany(typeof(IOperation))]
private List<IOperation> _knownOperations;
private List<ICalculatorButton> _buttons;
private CompositionContainer _container;
public Calculator()
{
_container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container.SatisfyImportsOnce(this);
_buttons = new List<ICalculatorButton>();
ICalculatorButton button;
for (int i = 0; i < 10; i++)
{
button = _container.GetExportedValue<IDigitButton>();
button.Symbol = i.ToString();
((IDigitButton)button).Value = i;
_buttons.Add(button);
}
foreach (IOperation op in _knownOperations)
{
button = _container.GetExportedValue<IOperationButton>();
button.Symbol = op.Symbol;
((IOperationButton)button).Operation = op;
_buttons.Add(button);
}
}
public IReadOnlyList<IOperation> KnownOperations
{
get { return _knownOperations.AsReadOnly(); }
}
public IReadOnlyList<ICalculatorButton> Buttons
{
get { return _buttons.AsReadOnly(); }
}
public IOperand Calculate(IOperation operation, params IOperand[] operands)
{
IOperand result = operation.Compute(operands);
return result;
}
public IOperand Calculate(IOperation operation, params double[] operands)
{
List<IOperand> res = new List<IOperand>();
foreach (double item in operands)
{
IOperand aux = _container.GetExportedValue<IOperand>();
aux.Value = item;
res.Add(aux);
}
return Calculate(operation, res.ToArray());
}
}
Где экспортирован 'реализация IOperand'? Вы должны просто импортировать его с помощью атрибута '[Import]' и вообще не иметь ссылки на контейнер, предполагая, что композиция происходит в другом месте. – Matt
@Matt Я отредактировал вопрос и вставил реализацию IOperand. Дело в том, что я не думаю, что хочу «Импортировать» его ... Я хочу каждый раз предоставлять новый экземпляр Calculate называется – Leonardo