为什么我的实现总是调用相同的派生 class?

Why is my implementation always calling the same derived class?

我有一个接受 Type 作为构造函数参数的基 class,以及两个从该基 class 继承的派生 class。我也有那个基础的接口class,我注入到其他地方使用。

当我调用基本方法 "FormatValue" 时,传递不同的类型作为参数,我总是得到相同的结果(它调用 classes 之一的方法,忽略我的类型参数) .

我做错了什么?

public interface IFormatService
{
    string FormatValue(object value);
}
public abstract class FormatService : IFormatService
{
    protected FormatService(Type type)
    { }

    public abstract string FormatValue(object value);
}

public static class Program
{
    private static void Main(string[] args)
    {
        var serviceProvider = new ServiceCollection()
            .AddSingleton<IFormatService, CurrencyFormat>()
            .AddSingleton<IFormatService, DateTimeFormat>()
            .BuildServiceProvider();

        var formatService = serviceProvider.GetService<IFormatService>();

        Console.WriteLine(formatService.FormatValue(DateTime.Now));
        Console.WriteLine(formatService.FormatValue(200));

        Console.ReadLine();
    }
}

public class CurrencyFormat : FormatService
{
    public CurrencyFormat() : base(typeof(decimal))
    {
    }

    public override string FormatValue(object value) => "CurrencyFormatter";
}

public class DateTimeFormat : FormatService
{
    public DateTimeFormat() : base(typeof(DateTime))
    {
    }

    public override string FormatValue(object value) => "DateTimeFormatter";
}

当前结果:

DateTimeFormatter
DateTimeFormatter

预期结果:

DateTimeFormatter
CurrencyFormatter

下面指出的代码会覆盖您之前的 CurrencyFormat 注册,因此它始终解析为 DateTimeFormat。

var serviceProvider = new ServiceCollection()
    .AddSingleton<IFormatService, CurrencyFormat>()
    .AddSingleton<IFormatService, DateTimeFormat>() <---------
    .BuildServiceProvider();

如果你想根据参数的类型调用不同的方法,有很多种方法。

一种方法是使用 dynamic 在运行时选择最佳重载:

public interface IFormatService
{
    string FormatValue(object value);
}

public class FormatService : IFormatService
{
    public string FormatValue(object value)
    {
        dynamic valueAsDynamic = value;

        return FormatValueDynamic(valueAsDynamic);
    }

    string FormatValueDynamic(dynamic value) => FormatValuePrivate(value);

    string FormatValuePrivate(DateTime value) => "DateTimeFormatter";

    string FormatValuePrivate(decimal value) => "CurrencyFormatter";

    string FormatValuePrivate(object value) => throw new NotSupportedException();
}

这样你就可以添加所有你需要的方法了。