Ninject 多个绑定取决于 ctor 参数名称
Ninject multiple bindings depending on ctor parameter name
假设我有如下界面:
public interface ISomething { };
public interface IResolver
{
string ResolveBy(ISomething something);
}
现在我有两种解析器类型;一个提供最佳解决方案,但有可能失败的解决方案和一个解析器,它总是 return 一个解决方案,应该作为后备策略:
public class UnsafeResolver : IResolver
{
Random random = new Random();
public string ResolveBy(ISomething something)
{
if (random.NextDouble() > 0.5)
{
return "best solution ever!";
}
else
{
throw new InvalidOperationException("something went wrong...");
}
}
}
public class SafeResolver : IResolver
{
public string ResolveBy(ISomething something)
{
return "fallback solution";
}
}
现在我想在 safeguarded 组合装饰器中组合两个解析器:
public class SafeguardedResolver : IResolver
{
private readonly IResolver unsafeResolver;
private readonly IResolver safeResolver;
// This is the problem with Ninject: Two parameters with same interface...
public SafeguardedResolver(IResolver unsafeResolver, IResolver safeResolver)
{
// guards omitted!
this.unsafeResolver = unsafeResolver;
this.safeResolver = safeResolver;
}
public string ResolveBy(ISomething something)
{
try
{
return unsafeResolver.ResolveBy(something);
}
catch (InvalidOperationException)
{
return safeResolver.ResolveBy(something);
}
}
}
所以我的问题是:如何在不使用的情况下使用Named Binding策略实现与Ninject的绑定?我不希望对我域中的容器有任何依赖性 类,因此建议的解决方案对我不起作用
当然不用将 ctor 更改为 IEnumerable<IResolver>
- 我想要两个单独的 明确命名的 参数!
为什么不能通过参数名称定义绑定?例如这样的事情:
Bind<IResolver>().To<SafeguardedResolver>();
Bind<IResolver>().To<UnsafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("unsafeResolver");
Bind<IResolver>().To<SafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("safeResolver");
不是可以通过反射获取参数名称吗?
我希望有人能给我一个答案,如何解决这个问题(也许通过使用另一个 DI 框架?)或者为什么这是不可能的。
I do not want any dependencies to the container in my domain classes
您可以在不从 class 库引用容器的情况下使用命名绑定,方法如下:
StandardKernel kernel = new StandardKernel();
kernel
.Bind<IResolver>()
.To<SafeguardedResolver>()
.WithConstructorArgument("unsafeResolver", c => c.Kernel.Get<IResolver>("unsafe"))
.WithConstructorArgument("safeResolver", c => c.Kernel.Get<IResolver>("safe"));
kernel
.Bind<IResolver>()
.To<UnsafeResolver>()
.Named("unsafe")
.BindingConfiguration.IsImplicit = true;
kernel
.Bind<IResolver>()
.To<SafeResolver>()
.Named("safe")
.BindingConfiguration.IsImplicit = true;
这里是你如何用 Pure DI 做同样的事情:
var result = new SafeguardedResolver(new UnsafeResolver(), new SafeResolver());
Pure DI 在此类情况下的简单性是 IMO it is better than using a container 的原因之一。
假设我有如下界面:
public interface ISomething { };
public interface IResolver
{
string ResolveBy(ISomething something);
}
现在我有两种解析器类型;一个提供最佳解决方案,但有可能失败的解决方案和一个解析器,它总是 return 一个解决方案,应该作为后备策略:
public class UnsafeResolver : IResolver
{
Random random = new Random();
public string ResolveBy(ISomething something)
{
if (random.NextDouble() > 0.5)
{
return "best solution ever!";
}
else
{
throw new InvalidOperationException("something went wrong...");
}
}
}
public class SafeResolver : IResolver
{
public string ResolveBy(ISomething something)
{
return "fallback solution";
}
}
现在我想在 safeguarded 组合装饰器中组合两个解析器:
public class SafeguardedResolver : IResolver
{
private readonly IResolver unsafeResolver;
private readonly IResolver safeResolver;
// This is the problem with Ninject: Two parameters with same interface...
public SafeguardedResolver(IResolver unsafeResolver, IResolver safeResolver)
{
// guards omitted!
this.unsafeResolver = unsafeResolver;
this.safeResolver = safeResolver;
}
public string ResolveBy(ISomething something)
{
try
{
return unsafeResolver.ResolveBy(something);
}
catch (InvalidOperationException)
{
return safeResolver.ResolveBy(something);
}
}
}
所以我的问题是:如何在不使用的情况下使用Named Binding策略实现与Ninject的绑定?我不希望对我域中的容器有任何依赖性 类,因此建议的解决方案对我不起作用
当然不用将 ctor 更改为 IEnumerable<IResolver>
- 我想要两个单独的 明确命名的 参数!
为什么不能通过参数名称定义绑定?例如这样的事情:
Bind<IResolver>().To<SafeguardedResolver>();
Bind<IResolver>().To<UnsafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("unsafeResolver");
Bind<IResolver>().To<SafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("safeResolver");
不是可以通过反射获取参数名称吗?
我希望有人能给我一个答案,如何解决这个问题(也许通过使用另一个 DI 框架?)或者为什么这是不可能的。
I do not want any dependencies to the container in my domain classes
您可以在不从 class 库引用容器的情况下使用命名绑定,方法如下:
StandardKernel kernel = new StandardKernel();
kernel
.Bind<IResolver>()
.To<SafeguardedResolver>()
.WithConstructorArgument("unsafeResolver", c => c.Kernel.Get<IResolver>("unsafe"))
.WithConstructorArgument("safeResolver", c => c.Kernel.Get<IResolver>("safe"));
kernel
.Bind<IResolver>()
.To<UnsafeResolver>()
.Named("unsafe")
.BindingConfiguration.IsImplicit = true;
kernel
.Bind<IResolver>()
.To<SafeResolver>()
.Named("safe")
.BindingConfiguration.IsImplicit = true;
这里是你如何用 Pure DI 做同样的事情:
var result = new SafeguardedResolver(new UnsafeResolver(), new SafeResolver());
Pure DI 在此类情况下的简单性是 IMO it is better than using a container 的原因之一。