命令模式、EF Core、类型转换和 MS DI

Command pattern, EF Core, type casting and MS DI

提问人:nktdrkhv 提问时间:8/25/2023 更新时间:8/25/2023 访问量:25

问:

如何正确地组合这些应用程序?

今天,我正在努力完成域事件,或者类似的东西。 比方说,我有这个(不是真正的代码):

public abstract class ActionDataBase 
{ 
    int Id {get; set;} 
}

public interface ICommandHandler<T> where T : ActionDataBase
{ 
    public Task HandleAsync<T>(T actionData) 
}

然后它变成了

public class SayHelloToJohnActionData : ActionDataBase
{ 
    public string Name { get; set; } = "John" 
}

public class SayHelloToJohnActionHandler : ICommandHandler<SayHelloToJohnActionData>
{
    private SomeDeps _dep;

    public SayHelloToJohnActionHandler(SomeDeps dep) => _dep = dep;

    public Task HandleAsync(SayHelloToJohnActionData data)
    { 
        Console.WriteLine($"Hello, {data.Name}!");
    }
}

最后,我将其注册为服务,然后为 EF Core 创建一个实体

public class LovelyThing
{
    public int LovelyThingId  { get; set; }
    public ICollection<ActionDataBase> GoodFriends { get; set; }
}

重点是什么?我知道这段代码闻起来很臭,也缺乏经验,但在我看来,我想存储某些操作的所有基本数据,并且我想从 DI 容器中获取它的依赖项。所以最后一步是

foreach(var goodFriend in GoodFriends)
    await _dispatcher.Dispatch(goodFriend);

在某个地方,然后:

public ActionHandlerDispatcher : IActionHandlerDispatcher
{
    private ServiceProvider _sp;

    public ActionHandlerDispatcher(ServiceProvider sp) => _sp = sp;

    public Task DispatchAsync<T>(T actionData)
    {
        // WELL....
    }
}

我有一个 WELL 选项

var generic = typeof(ICommandHandler<>) 
var argType = actionData.GetType(); 
var constructed = generic.MakeGenericType(argType) 
var handler = (ICommandHandler<T>) _provider.GetRequiredService(constructed); // type casting error, because T is an ActionDataBase
await handler.Handler(actionData);

我的问题是我该如何处理它?我知道命令模式和域事件看起来不同,但我想这种方法对我来说应该是有用的。我将以 TPH 方式存储 ActionDataBase 的派生类型,而且它看起来非常可扩展。但是类型铸造部分让我很困惑。

似乎 IConverter 不是我的事Convert.ChangeType

C# 实体框架核心 强制转换 命令模式 microsoft-extensions-di

评论

0赞 Kristin 8/25/2023
是因为你想避免反射吗?如果是这样,则可以在 DI 中注册为开放泛型类型,然后使用具体的派生类型 .但是,这确实要求您在使用开放泛型类型 时知道该类型。ActionHandlerDispatcherActionHandlerDispatcherActionDataBaseActionHandlerDispatcher
0赞 nktdrkhv 8/25/2023
@Kristin我确实想避免在编译时使用 Switch 或任何其他显式工具来确定类型的部分,因为如果我要添加新的 ***ActionData 和 ***ActionHandler,我也必须更改显式确定代码部分。甚至可以通过父类型将这种类型的 Dtos 存储在 Db 中,然后用某些东西解析吗?因为处理程序需要依赖关系ICollection<ActionDataBase> GoodFriends

答: 暂无答案