通过泛型传递类类型而不是接口

本文关键字:接口 类型 泛型 | 更新日期: 2023-09-27 18:33:42

好的 我刚刚在我们的应用程序中实现了一个 Command-CommandHandler 模式,该模式将命令对象添加到队列中;然后通过 Castle Windsor 使用依赖注入以及通用方法来获取命令对象的相关处理程序。

命令界面是空白的,如下所示:

public interface ICommand
{
}

虽然 CommandHandler 接口是这样处理它的:

public interface ICommandHandler<TCommand> where TCommand : ICommand
{
    void Handle(TCommand command);
}

然后,这些命令由我希望通过队列发送的命令实现;然后通过DependencyRegistration包装器在Castle Windsor中注册,如下所示:

_dependencyRegister
    .AddRegistration<ICommandHandler<TestCommand>, TestCommandHandler>();

因此,将添加到队列中的每个命令都使用处理程序将 1 映射到 1;然后在 Castle Windsor 中注册;因此我们可以使用这样的泛型方法来获取特定 Command 对象的相关 CommandHandler:

private void HandleCommand<T>(T queueItem) where T: ICommand
{
    var handler = _dependencyResolver.Resolve<ICommandHandler<T>>();
    handler.Handle(queueItem);
}

最后一块是队列调度程序方法,如下所示:

private void DispatchQueueItem(ICommand queueItem)
{
    HandleCommand(queueItem);
}

对;问题是,当我从队列中拉出一个命令作为ICommand并将其传递给DispatchQueueItem方法时;当它被发送到HandleCommand方法时,"T"类型总是设置为"ICommand"接口;而不是接口的实际实现(DependencyRegistration示例代码中的TestCommand(。

我的问题是;如何设置 HandleCommand 方法采用实现的类型;而不是接口?

通过泛型传递类类型而不是接口

将调度方法更改为通用:

private void DispatchQueueItem<T>(T queueItem)
    where T: ICommand
{
    HandleCommand(queueItem);
}

更新 您可以强制 C# 以这种方式在运行时定义对象类型

private static void DispatchQueueItem(ICommand queueItem)
{
    HandleCommand((dynamic)queueItem);
}

我认为您希望它是接口的 - 但您只需要在其中定义一个方法合约 - 例如:

public interface ICommand
{
    void Execute();
}
//Concrete implementation:
public TestCommand : ICommand
{
    public void Execute()
    {
        //Do something
    }
}

然后,当您从 DI 中获取 ICommand 时 - 您可以调用 queueItem.Execute() - 这将引用您分配的任何具体实现。

您的队列将始终调度 ICommand。所以需要获得"引擎盖下"的类型:

private void HandleCommand<T>(T queueItem) where T: ICommand
{
  var typeParam = queueItem.GetType();
  var type = typeof(ICommandHandler<>).MakeGenericType(typeParam);
  var handler = _dependencyResolver.Resolve(type);

我不确定确切的罪法。手头没有温莎城堡的项目。