Укажите зависимость параметра времени выполнения в Unity

У меня есть класс, которому нужна строка в качестве параметра в его конструкторе, но этот параметр будет определяться вызывающим кодом. В то же время время жизни этого класса должно быть привязано к каждому HTTP-запросу. Итак, я создал собственный PerWebRequestTimelineManager и использовал его для моего целевого типа в файле конфигурации. Но поскольку строка в конструкторе должна определяться динамически, я не могу использовать ConstructorInjection через файл конфигурации. Я могу использовать абстрактную фабрику для решения проблемы динамической зависимости, но я не уверен в реализации: вы можете проверить приведенный ниже код и проверить подход. В частности, вызовы RegisterType и Resolve кажутся немного неуместными, хотя последовательные вызовы Resolve в приложении смогут получить один и тот же экземпляр:

public class PerformanceTracerFactory : IPerformanceTracerFactory
{
    private readonly IPerformanceTracer tracer;

    public IPerformanceTracer CreateInstance(string operationTitle)
    {
        _container.RegisterType<IPerformanceTracer, PerformanceTracer>(new InjectionConstructor(operationTitle));

        return _container.Resolve<IPerformanceTracer>();
    }
}

Соответствующая часть файла конфигурации:

<register type="IPerformanceTracer" mapTo="PerformanceTracer">
  <lifetime type="PerWebRequest"/>
</register>
<register type="IPerformanceTracerFactory" mapTo="PerformanceTracerFactory"/>

У меня есть еще один вопрос. В случае, если описанный выше способ настройки и внедрения зависимости с использованием кода правильный, то я думаю, что мне не нужны записи конфигурации. Я всегда могу использовать подходящую перегрузку, чтобы нажать настраиваемый менеджер времени жизни. В случае, если я хотел бы добиться того же, используя только файл конфигурации, то как мне закодировать решение?


person koder    schedule 20.02.2012    source источник


Ответы (1)


Если вы используете фабрику на основе контейнера, вам не нужно регистрировать/разрешать свой IPerformanceTracer при каждом вызове.

Зарегистрируйте сопоставление IPerformanceTracer --> PerformanceTracer один раз в файле конфигурации и используйте ParameterOverride при разрешении интерфейса.

public IPerformanceTracer CreateInstance(string operationTitle)
{
    return _container.Resolve<IPerformanceTracer>(new ParameterOverride("nameOfTheParameterInTheConstructorOfPerformanceTracer", operationTitle);
}
person Sebastian Weber    schedule 20.02.2012
comment
Большое спасибо за ответ, Себастьян. Он отлично решил проблему. У меня есть еще одна просьба, чтобы избежать подобных проблем из-за незнания полного API. Где лучше всего обратиться к документации Unity API? - person koder; 21.02.2012
comment
@ user608100 Мне жаль вас разочаровывать, но документация Unity в целом ужасна. Некоторую информацию можно найти в MSDN. Но вы должны выяснить большую часть этого материала самостоятельно. В настоящее время я работаю над двумя статьями, которые будут размещены на сайте Unity на CodePlex и проливают свет на внутренности Unity. Но на их перевод потребуется больше времени. - person Sebastian Weber; 21.02.2012