Tiêm logic xử lý dữ liệu vào lớp


10

Tôi muốn tìm cách thanh lịch hơn và đánh giá cao để tiêm bộ xử lý vào CommandProcessorDispatcherlớp. Hoặc nó có thể là một giải pháp khác (mục tiêu là tách riêng từng logic xử lý lệnh thành lớp độc lập). Có lẽ một số mẫu thiết kế có thể hữu ích ở đây.

public interface ICommand { }
public class StartCommand : ICommand { }
public class StopCommand : ICommand { }

public interface ICommandProcessor<in T> where T : ICommand
{
    void Process(T command);
}

public class StartCommandProcessor : ICommandProcessor<StartCommand>
{
    public void Process(StartCommand command) { }
}

public class StopCommandProcessor : ICommandProcessor<StopCommand>
{
    public void Process(StopCommand command) { }
}

public interface ICommandProcessorDispatcher
{
    void Process(ICommand command);
}

public class CommandProcessorDispatcher : ICommandProcessorDispatcher
{
    public CommandProcessorDispatcher(Dictionary<Type, Action<ICommand>> processors)
    {
        _processors = processors;
    }

    private readonly Dictionary<Type, Action<ICommand>> _processors;

    public void Process(ICommand command)
    {
        _processors[command.GetType()](command);
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        var dict = new Dictionary<Type, Action<ICommand>>
        {
            { typeof(StartCommand), x => new StartCommandProcessor().Process((StartCommand)x) },
            { typeof(StopCommand), x => new StopCommandProcessor().Process((StopCommand)x) },
        };

        var dispatcher= new CommandProcessorDispatcher(dict);
    }
}

Bạn đã cho MediatR chưa? Về cơ bản nó làm những gì bạn cần, và một số thứ nữa.
Philippe

Điều này thực sự cũ, vì vậy bất kỳ câu hỏi làm rõ nào có thể sẽ không được trả lời. Giống như, điều này có liên quan gì đến WPF hay UAP không? ICommandđược định nghĩa với những công nghệ đó và được sử dụng rộng rãi, vì vậy thật khó để ly dị điều đó khỏi tâm trí tôi. Mục tiêu cuối cùng là gì? Có lẽ khái niệm cơ bản có thể sử dụng một số tinh chỉnh.
Berin Loritsch

Câu trả lời:


1

Tôi tin rằng bạn có thể đơn giản hóa mọi thứ một chút, mà không cần quá nhiều nồi hơi, trong khi vẫn được hưởng một số loại an toàn.

Một ví dụ giả định:

public interface ICommand
{
}

#region Friends
public abstract class CommandProcessor
{
    internal abstract void Process(ICommand command);

    public abstract Type CommandType { get; }
}

public abstract class CommandProcessor<TCommand> : CommandProcessor
    where TCommand : ICommand
{
    internal override void Process(ICommand command)
    {
        Process((TCommand)command);
    }

    protected abstract void Process(TCommand command);

    public override Type CommandType { get { return typeof(TCommand); } }
}

public class CommandProcessorDispatcher
{
    public CommandProcessorDispatcher(IEnumerable<CommandProcessor> processors)
    {
        Processors = processors;
    }

    public void Process(ICommand command)
    {
        var found =
            Processors.
            FirstOrDefault
            (
                processor => processor.CommandType == command.GetType()
            );
        if (found == null)
        {
            throw new InvalidOperationException("no suitable processor found");
        }
        found.Process(command);
    }

    // (may just be protected only, depending on requirements)
    public IEnumerable<CommandProcessor> Processors { get; protected set; }
}
#endregion

public class StartCommand : ICommand
{
    public override string ToString()
    {
        return StartId.ToString();
    }

    public int StartId { get; set; }
}

public class StopCommand : ICommand
{
    public override string ToString()
    {
        return StopId.ToString();
    }

    public int StopId { get; set; }
}

public class StartCommandProcessor : CommandProcessor<StartCommand>
{
    protected override void Process(StartCommand command)
    {
        Console.WriteLine("START : " + command);
    }
}

public class EndCommandProcessor : CommandProcessor<StopCommand>
{
    protected override void Process(StopCommand command)
    {
        Console.WriteLine("STOP : " + command);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        var dispatcher =
            new CommandProcessorDispatcher
            (
                new CommandProcessor[]
                {
                    new StartCommandProcessor(),
                    new EndCommandProcessor()
                }
            );

        var start = new StartCommand { StartId = 123 };
        var stop = new StopCommand { StopId = 456 };

        dispatcher.Process(start);
        dispatcher.Process(stop);

        Console.ReadKey();
    }
}

Điều này làm cho các giả định ít hơn về cách các bộ xử lý lệnh được lưu trữ và không yêu cầu các đại biểu Hành động, điều mà tôi đã bỏ lỡ để xem mục đích trong ví dụ của bạn - cuối cùng, tôi nghĩ rằng tốt hơn là nên bỏ qua (từ ICommand đến một trong các triển khai của nó ) xảy ra tại một địa điểm, chỉ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.