C# 在使用基于约定的注册时,如何使用类型化工厂解析采用参数的组件?
Windsor说我们可以在C# 在使用基于约定的注册时,如何使用类型化工厂解析采用参数的组件?,c#,dependency-injection,inversion-of-control,castle-windsor,conventions,C#,Dependency Injection,Inversion Of Control,Castle Windsor,Conventions,Windsor说我们可以在TypedFactory方法调用中传递参数,这些参数将传递给工厂正在创建的类型的构造函数: 您还可以使用从调用方获取参数的方法来解析组件。您传入的参数将传递到容器的解析管道 使用基于约定的注册时,这是如何工作的?我在验证是否没有缺少组件以及配置是否正确时遇到异常,表示我要传递给构造函数的类型尚未注册 例如,以以下代码为例: public interface IWatcherFactory : IDisposable { IWatcher GetWatcher(I
TypedFactory
方法调用中传递参数,这些参数将传递给工厂正在创建的类型的构造函数:
您还可以使用从调用方获取参数的方法来解析组件。您传入的参数将传递到容器的解析管道
使用基于约定的注册时,这是如何工作的?我在验证是否没有缺少组件以及配置是否正确时遇到异常,表示我要传递给构造函数的类型尚未注册
例如,以以下代码为例:
public interface IWatcherFactory : IDisposable
{
IWatcher GetWatcher(ImportTarget importTarget);
}
注册到container.Register(Component.For().AsFactory())代码>
其中WatcherBase
是
public abstract class WatcherBase : IWatcher
{
public WatcherBase(ImportTarget importTarget, ILogger logger)
{
// ...
}
}
使用container.Register(class.fromthissembly().BasedOn().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().ImplementedBy())代码>因此,我似乎只需要在容器中注册ImportTarget
,它似乎已经完成了这项工作
container.Register(Component.For<ImportTarget>());
免责声明:我不知道这是否是正确的方法,但现在它工作正常,所以我一直在使用它,直到它出现任何其他问题。因此,这个问题涵盖了两个相关但独立的主题。我会依次回答
为什么温莎抱怨缺少导入目标
依赖关系?
这与您注册组件的方式没有任何关系,不管是按惯例注册、逐个注册还是(请不要)使用XML注册
请记住,Windsor在安全方面犯了错误,它并不认为您将仅通过使用类型化工厂方法获得对FolderWatcher
的依赖。
它尝试使用它所拥有的东西—也就是说,它查看它确实知道的组件,当意识到它没有用于导入目标的组件时,它生成此消息
请注意,这不是一个错误,而是一个警告。它让你注意到这样一个事实:如果你试图直接依赖FolderWatcher
,你就会失败
现在(参考您自己的答案),注册一个组件.For()
会让温莎闭嘴,但我猜(在没有看到其余代码的情况下)一个简单的ImportTarget
,就像您通过new ImportTarget()
获得的一样,如果没有正确设置WatcherFullyQualifiedName
,它是没有多大用处的。因此,这是掩盖问题,而不是解决问题
将组件选择器连接到类型化工厂的正确方法是什么?
这很简单,你在这里做得对。
就个人而言,除非您在其他地方的其他工厂使用它,否则我甚至不会在容器中注册WatcherFactoryComponentSelector
,而是转到.AsFactory(cfg=>cfg.SelectedWith(new WatcherFactoryComponentSelector())
,但这是一个小点
container.Register(Component.For<ImportTarget>());
container.Register(Component.For<WatcherFactoryComponentSelector>());
container.Register(Component.For<IWatcherFactory>().AsFactory(cfg => cfg.SelectedWith<WatcherFactoryComponentSelector>()));