NamedParameter
предназначен для настройки запрошенного компонента, а не всего графа зависимостей, параметр не распространяется в течение всего процесса регистрации, он не является параметром context .
Если вы хотите иметь контекст , вы можете реализовать такой компонент, который будет хранить некоторые свойства.
// interface
interface IContext {
T Get<T>(String name);
void Set<T>(String name, T value);
}
// registration
builder.RegisterType<FooContext>().As<IContext>();
builder.Register<IFoo>(c =>
{
var score = c.Resolve<IContext>().Get<Int32>("score");
if (score >= 100)
{
return new HappyFoo();
}
return new SadFoo();
});
// usage
using (ILifetimeScope scope = container.BeginLifetimeScope())
{
scope.Resolve<IContext>().Set("score", 90);
scope.Resolve<IFooUser>().useFoo();
}
Преимущество этого подхода состоит в том, что вы можете установитьсвойство context всякий раз, когда вы хотите в своей текущей области жизни.Вы также можете представить себе реализацию без метода Set
, который будет извлекать значение на основе того, что вы хотите.
Другой способ сделать то же самое - использовать зависимость Func<Int32, IFoo>
и методы TypedAs
builder.Register<IFoo>((c, p) =>
{
Int32 score = p.TypedAs<Int32>();
if (score >= 100)
{
return new HappyFoo();
}
return new SadFoo();
});
и, конечно, вы должны изменить интерфейс IFooUser
и реализацию
public class NormalFooUser : IFooUser
{
private readonly Func<Int32, IFoo> _fooBuilder;
public NormalFooUser(Func<Int32,IFoo> fooBuilder)
{
_fooBuilder = fooBuilder;
}
public void useFoo(Int32 score)
{
_fooBuilder(score).foo();
}
}