gpt4 book ai didi

c# - 使用通用子类型注册依赖项 - 对于 Mediatr

转载 作者:行者123 更新时间:2023-12-05 05:33:32 27 4
gpt4 key购买 nike

我意识到我看到了(非常相似的)问题,但这似乎与通常提出的问题略有不同。

我得到了这个通知/通知处理程序

public class GenericEvent<T> : INotification
{
public T Value { get; set; }
}

public class GenericEventHandler<T> : INotificationHandler<GenericEvent<T>>
{
public Task Handle(GenericEvent<T> notification, CancellationToken ct)
{
throw new NotImplementedException();
}
}

注册依赖项将给出以下 C# 编译器错误:

CS7003: Unexpected use of an unbound generic name

public static class RegistrationTest
{
public static void Register(IServiceCollection services)
{
services.AddTransient(
typeof(INotificationHandler<GenericEvent<>>), // <!-- CS7003 here
typeof(GenericEventHandler<>));
}
}

Screenshot of the CS7003 compiler error in the IDE

我的意思当然是,生成的错误是有道理的。但是必须有一些其他方法来实际注册。 FWIW,使用 OOTB DI 容器

最佳答案

使用 C#,您可以指定开放泛型(例如 typeof(IEnumerable<>))或封闭泛型(例如 typeof(IEnumerable<List<int>>)),但不能指定部分封闭泛型(例如 typeof(IEnumerable<List<>>))。这给出了 CS7003 编译错误。

部分封闭的泛型类型只能使用反射创建,例如:

Type partiallyClosed = typeof(IEnumerable<>).MakeGenericType(typeof(List<>));

但是,尽管您可以在运行时创建部分封闭的泛型类型,但您的 DI 容器 MS.DI 支持此功能。通常,这不会成为问题,因为成熟的 DI 容器能够在进行以下注册时找出您的类型约束:

// WARNING: Does not work
services.AddTransient(typeof(INotificationHandler<>), typeof(GenericEventHandler<>));

虽然此代码片段可以编译,但在应用于 MS.DI 时不起作用。那是因为 MS.DI 的泛型类型系统是“直截了当的”(尽管我宁愿说“天真”)。它只支持最简单形式的泛型类型映射,正如我在 this answer 中表达的那样最近。

唯一的解决方法(同时坚持使用 MS.DI)是显式注册每个必需的封闭实现:

services.AddTransient<INotificationHandler<GenericEvent<Foo>>,
GenericEventHandler<Foo>>();
services.AddTransient<INotificationHandler<GenericEvent<Bar>>,
GenericEventHandler<Bar>>();
services.AddTransient<INotificationHandler<GenericEvent<Zoo>>,
GenericEventHandler<Zoo>>();
services.AddTransient<INotificationHandler<GenericEvent<Rar>>,
GenericEventHandler<Rar>>();

另一种选择是转向更成熟、功能更丰富的 DI 容器。

关于c# - 使用通用子类型注册依赖项 - 对于 Mediatr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73813259/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com