c# - 在使用基于约定的注册时,如何使用类型化工厂来解析带参数的组件?
问题描述
Windsor 的文档说我们可以在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());
现在其他问题和答案说参数名称需要匹配才能工作,我的已经这样做了。
这是我得到的确切错误:
'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>());
解决方案
所以这个问题涵盖了两个相关但独立的主题。我会依次回答他们。
为什么温莎抱怨缺少ImportTarget
依赖?
这与您注册组件的方式没有任何关系,无论是按照惯例,一一注册还是(请不要)使用 XML。
请记住,Windsor 在安全方面犯了错误,它并不认为您只会FolderWatcher
通过使用类型化工厂方法获得对 的依赖。它尝试使用它所拥有的东西——也就是说,它查看它所知道的组件,并在意识到它没有一个组件时,ImportTarget
它会产生这个消息。
请注意,这不是错误,而是更多的警告。它的存在是为了让你注意这样一个事实,即如果你试图直接依赖它FolderWatcher
,你就会失败。
现在(参考您自己的答案),注册 aComponent.For<ImportTarget>()
将使 Windsor 闭嘴,但我猜(没有看到您的其余代码)一个普通的ImportTarget
,就像您得到的那样new ImportTarget()
不是很有用,没有WatcherFullyQualifiedName
正确设置。所以这是掩盖问题而不是解决问题。
将组件选择器连接到类型化工厂的正确方法是什么?
这很容易——你在这里做对了。就个人而言,除非您将它用于其他地方的其他工厂,否则我什至不会费心WatcherFactoryComponentSelector
在容器中注册,但是 go .AsFactory(cfg => cfg.SelectedWith(new WatcherFactoryComponentSelector()))
,但这是一个小问题。
推荐阅读
- ios - 节拍器。定时器、音乐和动画
- reactjs - 与 TypeScript 反应 - 类型 {...} 不可分配给类型“只读
” - javascript - Javascript:IE 的等效解构赋值
- reactjs - Safari & event.target.select()
- php - @php artisan package:discover 处理返回的自动加载转储后事件,错误代码为 255
- laravel - 在 laravel 中显示数据库中的多个图像
- xml - how to group XML without attributes
- javascript - 将 CSS 值存储在 JavaScript 变量中
- node.js - NodeJS + CloudSQL Postgres - 连接随机终止
- reactjs - 将 typeahead bootstrap 与 Elasticsearch 一起使用