Почему моя реализация всегда вызывает один и тот же производный класс? - PullRequest
1 голос
/ 06 июня 2019

У меня есть базовый класс, который принимает тип в качестве аргумента конструктора, и два производных класса, которые наследуются от этого базового класса.У меня также есть интерфейс этого базового класса, который я использую в других местах.

Когда я вызываю базовый метод "FormatValue", передавая различные типы в качестве параметров, я всегда получаю один и тот же результат (это вызовметод в одном из классов, игнорируя мой параметр типа).

Что я делаю не так?

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

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Код, указанный ниже, переопределяет вашу предыдущую регистрацию CurrencyFormat, поэтому он всегда преобразуется в DateTimeFormat.

var serviceProvider = new ServiceCollection()
    .AddSingleton<IFormatService, CurrencyFormat>()
    .AddSingleton<IFormatService, DateTimeFormat>() <---------
    .BuildServiceProvider();
0 голосов
/ 06 июня 2019

Если вы хотите вызывать разные методы в зависимости от типа параметра, есть много способов сделать это.

Один из способов - использовать 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();
}

Таким образом, вы можете добавить все необходимые методы.

...