【问题标题】:Castle Windsor with Multiple Constructors具有多个构造函数的温莎城堡
【发布时间】:2009-11-17 03:23:44
【问题描述】:

我目前正在进行转换,从使用 Ninject 到当前版本的 Castle Windsor,用于一个简单的 C# .NET 应用程序。

在大多数情况下,转换进展顺利,容器的实施完美无缺。但是,我的存储库对象有一个小问题。

我有一个按以下方式编码的用户存储库对象:

public class UserRepository : IUserRepository {
    public UserRepository(IObjectContext objectContext)  {
        // Check that the supplied arguments are valid.
        Validate.Arguments.IsNotNull(objectContext, "objectContext");

        // Initialize the local fields.
        ObjectContext = objectContext;
    }

    public UserRepository(IObjectContextFactory factory) 
        : this(factory.CreateObjectContext()) { 
    }

    // -----------------------------------------------
    // Insert methods and properties...
    // -----------------------------------------------
}

为了对应此代码,我在应用程序的配置文件中设置了以下条目:

<castle>
    <components>
        <component id="objectContextFactory" lifestyle="custom"
                   customLifestyleType="Common.Infrastructure.PerWebRequestLifestyleManager, Common.Castle"
                   service="Project.DAL.Context.IObjectContextFactory, Project.DAL.LINQ"
                   type="project.DAL.Context.ObjectContextFactory, Project.DAL.LINQ">
        </component>
        <component id="userRepository" lifestyle="custom"
                   customLifestyleType="Common.Infrastructure.PerWebRequestLifestyleManager, Common.Castle"
                   service="Project.BL.Repository.IUserRepository, Project.BL"
                   type="Project.BL.Repository.UserRepository, Project.BL.LINQ">
            <parameters>
              <factory>${objectContextFactory}</factory>
            </parameters>
        </component>
    </components>
</castle>

对我来说,一切看起来都应该如此。当我尝试解析 IObjectContextFactory 服务的实例时,我检索了一个 ObjectContextFactory 对象。当我尝试解决 IUserRepository 服务的实例时,我的问题就出现了。我遇到了以下令人愉快的例外情况:

无法创建组件“userRepository”,因为它需要满足依赖关系。 userRepository 正在等待以下依赖项:

服务:

- SandCastle.DAL.Context.IObjectContext which was not registered.

我已经尝试了我能想到的一切。所以,对于你们 stackoverflow 读者,我说:有什么想法吗?

【问题讨论】:

    标签: c# dependency-injection castle-windsor constructor


    【解决方案1】:

    这可能被视为一个错误(实际上对于这种情况它是可以修复的),但它是一种设计特性。

    Windsor 尝试匹配它可以满足的最贪婪的构造函数(具有最多参数的构造函数)。

    但是,在您的情况下,有两个构造函数的参数数量最多(一个),因此 Windsor 只选择第一个,其中“第一个”的含义未定义。

    确实,如果您在源代码中切换构造函数的顺序,您的代码将开始工作,尽管它是一种 hack,依赖于未记录的行为并且不要这样做。

    让我们回到我们开始的地方好吗?

    我说温莎很困惑,因为没有单个它可以满足的最贪婪的构造函数。

    快速且定义明确的解决方法是向其中一个构造函数添加一个假参数,以便它们具有不同数量的参数:

    public class UserRepository : IUserRepository {
        public UserRepository(IObjectContext objectContext, object fakeIgnoreMe)  {
            // Check that the supplied arguments are valid.
            Validate.Arguments.IsNotNull(objectContext, "objectContext");
            // ignoring fake additional argument
            // Initialize the local fields.
            ObjectContext = objectContext;
        }
    
        public UserRepository(IObjectContextFactory factory) 
            : this(factory.CreateObjectContext()) { 
        }
    
        // -----------------------------------------------
        // Insert methods and properties...
        // -----------------------------------------------
    }
    

    请将此问题报告给Castle users liststraight to issue tracker,以便得到修复。

    【讨论】:

    • 工作得像黑帮!谢谢!
    • “Windsor 尝试匹配最贪婪的构造函数(它可以满足的参数最多的构造函数)”。我认为“从只包含可解析参数的构造函数列表中,选择具有最多参数的构造函数”更正确。
    • @KrzysztofKoźmic:我认为添加“(”和“)”可以做到这一点:-)
    • @KrzysztofKoźmic:我喜欢和你讨论这个构造函数解析行为。是否有我们可以就此进行沟通的渠道(例如邮件)?
    • 城堡用户谷歌组怎么样?这通常是最好的地方
    【解决方案2】:

    从 Windsor 3.2.x 开始

    如果属性Castle.Core.DoNotSelectAttribute 应用于构造函数,则不会被选中,尽管有任何其他条件。

    public class UserRepository : IUserRepository
    {
        [DoNotSelect] // This constructor will be ignored by Windsor
        public UserRepository(IObjectContext objectContext)
        {
            // ...
        }
    
        public UserRepository(IObjectContextFactory factory)
            : this(factory.CreateObjectContext()) {}
    }
    

    参考:https://github.com/castleproject/Windsor/blob/86696989a7698c45b992eb6e7a67b765b48108b0/docs/how-constructor-is-selected.md

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多