我目前正在进行转换,从使用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读者,我说:有任何想法吗?
答案 0 :(得分:7)
这可能被视为一个错误(事实上对于像这样的情况它是可以修复的)但它有点像设计特征。
Windsor尝试匹配它可以满足的最贪婪的构造函数(具有最多参数的构造函数)。
但是在你的情况下,有两个构造函数具有最多的参数(一个),所以Windsor只选择第一个,其中“first”意味着未定义。
事实上,如果你在源代码中切换构造函数的顺序,你的代码将开始工作,虽然它是一个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 list或straight to issue tracker,以便修复。
答案 1 :(得分:0)
如果属性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()) {}
}