Dependency injection 如何将GetAll与Ninject结合使用,以避免一次失败';无法阻止其他绑定解析?

Dependency injection 如何将GetAll与Ninject结合使用,以避免一次失败';无法阻止其他绑定解析?,dependency-injection,ninject,inversion-of-control,ioc-container,Dependency Injection,Ninject,Inversion Of Control,Ioc Container,为mutli注入提供的某些绑定可能无法解析 public List<IMyCommand> GetMyCommands() { //throws return kernel.GetAll<IMyCommand>().ToList(); } public List GetMyCommands() { //投掷 返回kernel.GetAll().ToList(); } 我仍然希望获得所有成功解析的对象,以及理想情况

为mutli注入提供的某些绑定可能无法解析

    public List<IMyCommand> GetMyCommands()
    {
        //throws
        return kernel.GetAll<IMyCommand>().ToList();
    }
public List GetMyCommands()
{
//投掷
返回kernel.GetAll().ToList();
}
我仍然希望获得所有成功解析的对象,以及理想情况下哪些对象失败。有没有办法用Ninject实现这一点?

不是现成的。 但我们可以创建某种黑客/解决方法小心。我宁愿实现一些明确处理我的案例的特定机制,也不愿让Ninject参与其中

但对于好奇的人,你可以这样说:

如果查看
IResolutionRoot.TryGet
的实现,您将看到它所做的只是捕获
ActivationException
并在这种情况下返回
default(T)

我们可以创建自己的
TryGetAll
,它也可以这样做,但不是为整个
IRequest
创建,而是分别为每个绑定创建。下面是如何做到这一点:

public static class ResolutionRootExtensions
{
    public static IEnumerable<T> TryGetAll<T>(this IResolutionRoot resolutionRoot)
    {
        var request = resolutionRoot.CreateRequest(
            typeof(IFoo),
            x => true,
            Enumerable.Empty<IParameter>(),
            true,
            false);
        IEnumerable results = resolutionRoot.Resolve(request);
        IEnumerator enumerator = results.GetEnumerator();

        while (MoveNextIgnoringActivationException(enumerator))
        {
            yield return (T)enumerator.Current;
        }
    }

    private static bool MoveNextIgnoringActivationException(
       IEnumerator enumerator)
    {
        while (true)
        {
            try
            {
                return enumerator.MoveNext();
            }
            catch (ActivationException)
            {
            }
        }
    }
}
公共静态类ResolutionRootExtensions
{
公共静态IEnumerable TryGetAll(此IResolutionRoot resolutionRoot)
{
var request=resolutionRoot.CreateRequest(
类型(IFoo),
x=>正确,
Enumerable.Empty(),
是的,
假);
IEnumerable results=resolutionRoot.Resolve(请求);
IEnumerator枚举器=结果。GetEnumerator();
while(MoveNextIgnoringActivationException(枚举器))
{
产生返回(T)枚举数.Current;
}
}
私有静态bool MoveNextIgnoringActivationException(
IEnumerator(枚举器)
{
while(true)
{
尝试
{
返回枚举数.MoveNext();
}
捕获(激活异常)
{
}
}
}
}
我已经对它进行了测试,它可以工作:

public class Test
{
    [Fact]
    public void Foo()
    {
        var kernel = new StandardKernel();

        kernel.Bind<IFoo>().To<FooA>();
        kernel.Bind<IFoo>().To<FooWithDependencyD>();
        kernel.Bind<IFoo>().To<FooB>();
        kernel.Bind<IFoo>().To<FooC>();
        kernel.Bind<IFoo>().To<FooWithDependencyE>();

        kernel.TryGetAll<IFoo>().Should()
            .HaveCount(3)
            .And.Contain(x => x.GetType() == typeof(FooA))
            .And.Contain(x => x.GetType() == typeof(FooB))
            .And.Contain(x => x.GetType() == typeof(FooC));
    }
}

public interface IFoo
{
}

class FooA : IFoo { }

class FooB : IFoo { }

class FooC : IFoo { }

class FooWithDependencyD : IFoo
{
    private readonly IDependency _dependency;

    public FooWithDependencyD(IDependency dependency)
    {
        _dependency = dependency;
    }
}

class FooWithDependencyE : IFoo
{
    private readonly IDependency _dependency;

    public FooWithDependencyE(IDependency dependency)
    {
        _dependency = dependency;
    }
}

internal interface IDependency
{
}
公共类测试
{
[事实]
公共图书馆
{
var kernel=新的标准内核();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().To();
kernel.TryGetAll().Should()
.HaveCount(3)
.And.Contain(x=>x.GetType()==typeof(FooA))
.And.Contain(x=>x.GetType()==typeof(FooB))
.And.Contain(x=>x.GetType()==typeof(FooC));
}
}
公共接口IFoo
{
}
类FooA:IFoo{}
类FooB:IFoo{}
类FooC:IFoo{}
类FooWithDependencyD:IFoo
{
私有只读独立性_依赖性;
公共食品WithDependencyD(IDEDependency dependency)
{
_依赖=依赖;
}
}
类FooWithDependencyE:IFoo
{
私有只读独立性_依赖性;
具有依赖项的公共食品(IDependency依赖项)
{
_依赖=依赖;
}
}
内部接口独立性
{
}

您的对象怎么可能无法解析?通常不应忽略对象图中对象构造的失败,因为其中一些可能是由插件提供的,或者,解析可能通过IProvider从另一个容器转发,该容器可能通过插件填充。。。知道这一点是否真的有助于回答我的问题,或者只是说我不应该问这个问题。知道这一点无助于回答这个具体问题,但它强化了我的观点,即我最初的反应是正确的。当然你可以问这个问题,但是我认为如果你改变了你的设计,你根本不需要问这个问题。如果存在某些注册,则必须能够解决它。不这样做是应用程序中的一个错误。如果插件没有提供这样的命令,它就不应该出现在列表中,这样你就可以在没有失败风险的情况下解析完整的列表。我最后写了这样的东西,虽然我最终返回了一个“解析程序”列表,每个解析程序都可以被调用来解析特定的上下文,这样,任何异常都可以被捕获并得到适当的处理。是的,无论如何,我认为这要好得多。