C# 在使用基于约定的注册时,如何使用类型化工厂解析采用参数的组件?

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

Windsor说我们可以在
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>()));