通过下一级服务向依赖项传递参数



如果我能准确地解析具有命名参数的服务,我就能理解如何解析该参数。但问题是,在我的情况下,我有这样的服务作为一个依赖。以下是示例:

class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<Dependency>();
builder.RegisterType<Something>();
var container = builder.Build();
container.Resolve<Dependency>(new NamedParameter("prm", "test"));
container.Resolve<Something>(new NamedParameter("prm", "test")); //Fails
}
}
class Dependency
{
public Dependency(string prm) { }
}
class Something
{
public Something(Dependency dep) { }
}

它在第二次Resolve调用时失败,但我需要这样的东西。你能提出解决问题的建议吗?也许我应该把参数标记成这样:

container.Resolve<Something>(new NamedParameter<Dependency>("prm", "test"));

这就是我解决特定问题的方法。它同时支持动态(运行时(和静态(编译时(值:

class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<Dependency2>();
builder.RegisterGeneric(typeof(SomethingFactory<>));
builder.RegisterType<Something>().WithAttributeFiltering();
var container = builder.Build();
Console.WriteLine(container.Resolve<Something>()
.GetPrm());
Console.WriteLine(container.Resolve<SomethingFactory<Something>>()
.GetService(new Dependency1("My test value from the factory")).GetPrm());
Console.WriteLine("But the registration is " + container.IsRegistered<Dependency1>());
}
}
class Dependency1
{
private readonly string _prm;
public Dependency1(string prm) => _prm = prm;
public string GetPrm() => _prm;
}
class Dependency2
{
private readonly Dependency1 _dep;
public Dependency2(Dependency1 dep) => _dep = dep;
public string GetPrm() => _dep.GetPrm();
}
class Something
{
private readonly Dependency2 _dep;
public Something([Prm("My test value from the attribute")]Dependency2 dep) => _dep = dep;
public string GetPrm() => _dep.GetPrm();
}
class Prm : ParameterFilterAttribute
{
private readonly string _prm;
public Prm(string prm) => _prm = prm;
public override bool CanResolveParameter(ParameterInfo parameter, IComponentContext context)
=> !context.IsRegistered<Dependency1>();
public override object ResolveParameter(ParameterInfo parameter, IComponentContext context)
{
if (parameter == null)
{
throw new ArgumentNullException(nameof(parameter));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var container = context.Resolve<ILifetimeScope>();
using var scope = container.BeginLifetimeScope(builder
=> builder.RegisterInstance(new Dependency1(_prm)));
return scope.Resolve(parameter.ParameterType);
}
}
class SomethingFactory<T>
{
private readonly ILifetimeScope _container;
public SomethingFactory(ILifetimeScope container)
{
_container = container;
}
public T GetService(Dependency1 dep)
{
if (dep == null)
{
throw new ArgumentNullException(nameof(dep));
}
using var scope = _container.BeginLifetimeScope(builder => builder.RegisterInstance(dep));
return scope.Resolve<T>();
}
}
My test value from the attribute
My test value from the factory
But the registration is False

最新更新