温莎的docs说我们可以在TypedFactory
方法调用中传递参数,这些参数将传递给工厂正在创建的类型的构造函数:
您还可以使用从调用方获取参数的方法来解析组件。您传入的参数将被传递到容器的解析管道。
使用基于约定的注册时,该如何工作?验证没有丢失的组件并且我的配置正确时,我得到一个异常,说我要传递给构造函数的类型尚未注册。
例如,采用以下代码:
public interface IWatcherFactory : IDisposable
{
IWatcher GetWatcher(ImportTarget importTarget);
}
已在container.Register(Component.For<IWatcherFactory>().AsFactory());
中注册
public class FolderWatcher : WatcherBase
{
public FolderWatcher(ImportTarget importTarget, ILogger logger, IClock clock, IFileSystem fileSystem)
: base(importTarget, logger)
{
// ...
}
}
WatcherBase
是
public abstract class WatcherBase : IWatcher
{
public WatcherBase(ImportTarget importTarget, ILogger logger)
{
// ...
}
}
已在container.Register(Classes.FromThisAssembly().BasedOn<IWatcher>().WithServiceAllInterfaces().LifestyleTransient());
现在还有其他问题和答案say,参数名称需要与此匹配才能起作用,而我已经做到了。
这是我得到的确切错误:
'FolderWatcher' is waiting for the following dependencies:
- Service 'ImportTarget' which was not registered.
我认为问题在于,没有人告诉温莎,由于惯例注册,对ImportTarget
的依赖存在,但是我不确定。
我还有一个看起来像这样的组件选择器:
public class WatcherFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
var config = arguments.FirstOrDefault() as ImportTarget;
if (config == null)
{
return base.GetComponentName(method, arguments);
}
return config.WatcherFullyQualifiedName;
}
}
其注册方式如下:container.Register(Component.For<ITypedFactoryComponentSelector>().ImplementedBy<WatcherFactoryComponentSelector>());
答案 0 :(得分:1)
因此,问题涵盖了两个相关但独立的主题。我会依次回答。
ImportTarget
依存关系?这与您注册组件的方式没有任何关系,无论是按照惯例,是一个接一个还是(请不要)使用XML。
请记住,温莎在安全方面犯了错误,并且不认为您会仅使用类型化工厂方法来获得对FolderWatcher
的依赖。
它会尝试使用现有功能-也就是说,它会调查它确实知道的组件,并且在意识到ImportTarget
中没有它的情况下,会产生此消息。
请注意,这不是错误,而是更多警告。在这里引起您的注意的事实是,如果您尝试直接直接依赖于FolderWatcher
,那么您将失败。
现在(参考您自己的回答),注册一个Component.For<ImportTarget>()
会使Windsor闭嘴,但是我猜(没有看到您的其余代码)是一个普通的ImportTarget
,就像如果没有正确设置new ImportTarget()
,那么WatcherFullyQualifiedName
会给您带来的帮助不是很有用。这样就掩盖了问题,而不是解决问题。
这很容易-您在这里做对了。
就个人而言,除非您将其用于其他地方的其他工厂,否则我什至都不会在容器中注册WatcherFactoryComponentSelector
,而是去.AsFactory(cfg => cfg.SelectedWith(new WatcherFactoryComponentSelector()))
,但这只是次要的事情。
答案 1 :(得分:0)
所以看来我需要做的就是在容器中注册ImportTarget
,这似乎已经完成了工作。
container.Register(Component.For<ImportTarget>());
我还需要更改注册IWatcherFactory
的方式:
container.Register(Component.For<WatcherFactoryComponentSelector>());
container.Register(Component.For<IWatcherFactory>().AsFactory(cfg => cfg.SelectedWith<WatcherFactoryComponentSelector>()));
免责声明:我不知道这是否是正确的处理方式,但是现在它可以正常工作,因此我会一直使用它,直到出现其他问题