如何在 Winform .net core 上使用 MediatR

unh*_*tle 2 c# dependency-injection winforms .net-core mediatr

我有一个 .net 核心 winform 应用程序,正在实现 n 层架构(ApplicationLayer(winform)、BLL、DAL)

已安装 MediatR 和 MediatR.Extensions.Microsoft.DependencyInjection

我目前正在关注这个网站:

https://dotnetcoretutorials.com/2019/04/30/the-mediator-pattern-part-3-mediatr-library/

我把这段代码放在哪里

public void ConfigureServices(IServiceCollection services)
{
    services.AddMediatR(Assembly.GetExecutingAssembly());
    //Other injected services. 
}
Run Code Online (Sandbox Code Playgroud)

我试过像这样把它放在 Main() 上:

    static class Program
{
    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(IServiceCollection services)
    {
        services.AddMediatR(Assembly.GetExecutingAssembly());
        services.AddTransient<IApplicationHandler, ApplicationHandler>();

        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Run Code Online (Sandbox Code Playgroud)

它给了我这个错误

程序不包含适合入口点的静态“Main”方法

And*_*osa 5

Main()方法是应用程序的入口点,因此无法修改。当您向它添加参数时,编译器告诉它找不到Main()(无参数)方法。

如果您想使用依赖注入 + windows 表单,则需要一些额外的步骤。

1 - 安装包Microsoft.Extensions.DependencyInjection。Windows 窗体本身没有 DI 功能,因此我们需要添加它。

2 - 把你的Program.cs班级改成这样

static class Program
{
    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {

        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // This class will contains your injections
        var services = new ServiceCollection();
       
        // Configures your injections
        ConfigureServices(services);

        // Service provider is the one that solves de dependecies
        // and give you the implementations
        using (ServiceProvider sp = services.BuildServiceProvider())
        {
            // Locates `Form1` in your DI container.
            var form1 = sp.GetRequiredService<Form1>();
            // Starts the application
            Application.Run(form1);
        }

    }

    // This method will be responsible to register your injections
    private static void ConfigureServices(IServiceCollection services)
    { 
        // Inject MediatR
        services.AddMediatR(Assembly.GetExecutingAssembly());
        
        // As you will not be able do to a `new Form1()` since it will 
        // contains your injected services, your form will have to be
        // provided by Dependency Injection.
        services.AddScoped<Form1>();

    }
}
Run Code Online (Sandbox Code Playgroud)

3 - 创建您的命令请求

public class RetrieveInfoCommandRequest : IRequest<RetrieveInfoCommandResponse>
{
    public string Text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

4 - 创建您的命令响应

public class RetrieveInfoCommandResponse
{
    public string OutputMessage { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

5 - 创建您的命令处理程序

public class RetrieveInfoCommandHandler : IRequestHandler<RetrieveInfoCommandRequest, RetrieveInfoCommandResponse>
{
    public async Task<RetrieveInfoCommandResponse> Handle(RetrieveInfoCommandRequest request, CancellationToken cancellationToken)
    {
        RetrieveInfoCommandResponse response = new RetrieveInfoCommandResponse();
        response.OutputMessage = $"This is an example of MediatR using {request.Text}";
        return response;
    }
}
Run Code Online (Sandbox Code Playgroud)

6 - Form1 实现

public partial class Form1 : Form
{
    private readonly IMediator _mediator;
    public Form1(IMediator mediator)
    {
        _mediator = mediator;
        InitializeComponent();

    }

    private async void button1_Click(object sender, EventArgs e)
    {
        var outputMessage = await _mediator.Send(new RetrieveInfoCommandRequest
        {
            Text = "Windows Forms"
        });

        label1.Text = outputMessage.OutputMessage;
    }
}
Run Code Online (Sandbox Code Playgroud)

工作代码

在此处输入图片说明

我从没想过在 Windows 窗体中使用 MediatR,这是一个很好的研究案例。好问题=)