c# - 创建递归嵌套实体的类型化工厂设施

标签 c# castle-windsor windsor-3.0

考虑需要创建一些递归嵌套的东西的情况,例如:

    public interface IRecurrentTestNodeFactory
    {
        RecurrentTestNode Create(int num);
    }

    public class RecurrentTestNode
    {
        public int Num { get; set; }
        public RecurrentTestNode Child { get; set; }

        public RecurrentTestNode(int num, IRecurrentTestNodeFactory factory)
        {
            Num = num;
            Child = num > 0 ? factory.Create(num - 1) : null;
        }
    }

明显的实现是这样的:

    public class ManualRecurrentTestNodeFactory : IRecurrentTestNodeFactory
    {
        public RecurrentTestNode Create(int num)
        {
            return new RecurrentTestNode(num, this);
        }
    }

    [Test]
    public void ManualRecurrentTest()
    {
        var root = new ManualRecurrentTestNodeFactory().Create(1);
        Assert.NotNull(root);
        Assert.AreEqual(1, root.Num);
        Assert.NotNull(root.Child);
        Assert.AreEqual(0, root.Child.Num);
        Assert.Null(root.Child.Child);
    }

这个测试通过了。但是,如果您尝试对 Windsor 的类型化工厂设施做同样的事情:

    [Test]
    public void RecurrentTest()
    {
        var windsor = new WindsorContainer();
        windsor.Kernel.AddFacility<TypedFactoryFacility>();
        windsor.Register(Component.For<IRecurrentTestNodeFactory>().AsFactory());
        windsor.Register(Component.For<RecurrentTestNode>().LifeStyle.Transient);

        var f = windsor.Resolve<IRecurrentTestNodeFactory>();
        var root = f.Create(1);
        Assert.NotNull(root);
        Assert.AreEqual(1, root.Num);
        Assert.NotNull(root.Child);
        Assert.AreEqual(0, root.Child.Num);
        Assert.Null(root.Child.Child);
    }

失败并出现以下异常:

Castle.MicroKernel.ComponentActivator.ComponentActivatorException : ComponentActivator: could not instantiate Tests.RecurrentTestNode
  ----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
  ----> Castle.MicroKernel.CircularDependencyException : Dependency cycle has been detected when trying to resolve component 'Tests.RecurrentTestNode'.
The resolution tree that resulted in the cycle is the following:
Component 'Tests.RecurrentTestNode' resolved as dependency of
    component 'Tests.RecurrentTestNode' which is the root component being resolved.

很明显为什么这样的代码在服务的情况下会失败,但对于工厂来说似乎没有必要限制。我想留在工厂变体中,因为我在那里有一堆容器解析的依赖项,而不是普通的 int。

最佳答案

懒惰地打破循环,而不是在构造函数中。温莎的行为是正确的。

关于c# - 创建递归嵌套实体的类型化工厂设施,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12566162/

相关文章:

c# - 不使用 saveChanges 更新 DBSet

C#如何对背景渐变进行base64编码

c# - 使用 CaSTLe 动态代理拦截所有依赖项

.net - 温莎城堡 : suppress exceptions thrown by Resolve()

c# - 限制 Windsor 容器解析基于的对象

c# - AWS Cognito 注册

c# - 如何让这个系统设计和逻辑更有效率? (内部消息系统)

caSTLe-windsor - 温莎城堡 : How can I update a components registration

c# - WCF & CaSTLe Windsor - 看起来你忘了

asp.net-mvc - CasTLe Winsor 3.0 NuGet 安装失败