gpt4 book ai didi

具有动态 Func<> 构造的 C# Fluent API

转载 作者:行者123 更新时间:2023-11-30 12:56:26 24 4
gpt4 key购买 nike

我正在创建一个带有流畅 API 的小型 SQL 库,并且想做这样的事情:

var person = connection.GetOne<Person>("select * from [Person] where [Id] = 1")
.WithMany<Pet>("select * from [Pet] where [PersonId] = 1")
.WithMany<Address>("select * from [Address] where [PersonId] = 1]")
.Build((person, pets, addresses) =>
{
person.Pets = pets;
person.Addresses = addresses;

return person;
});

我以前构建过很多流畅的 API,但所有 API 都简单得多,并且没有那么严重地依赖泛型。我的问题具体是如何着手实现 Build() 结束函数。我不确定它是否可能(看起来不像,但也许使用 Expression 是关键?)但是我如何跟踪在调用更高链方法(例如 GetOne<>( ), WithMany<>()) 以便在调用 .Build() 时所需的 Func<> 是正确的类型?

在上面的示例中,我希望 Func<> 为 Func , IEnumerable

> 以便开发人员可以按照他们需要的任何方式构建根项(人)-在这种情况下,用一个->多个查询的结果填充几个集合。

有什么办法可以做到这一点还是我运气不好?似乎很多地方我都在寻找类似的东西:

Func<In1, TResult>
Func<In1, In2, TResult>
Func<In1, In2, In3, TResult>
...etc, etc

...显然会限制函数参数的最大数量。

如有任何帮助或指点,我们将不胜感激。

最佳答案

如果您想要强大的自动完成功能并防止有人在您期望 (person, pet) => {} 时编写 .Build(person => {}) ,您需要在构建器中详细说明。

这是一个三层深度的例子:

class Person { public IEnumerable<Pet> Pets { get; set;} } class Pet {} class Address{}

public static class Builder
{
public static Level1<T> GetOne<T>(this object obj, string blah) {
return new Level1<T>();
}
}
public class Level1<T1> {
public Level2<T1, T2> WithMany<T2>(string blah) { return new Level2<T1, T2>(); }
public T1 Build(Func<T1, T1> pred) { return pred(default(T1)); }
}
public class Level2<T1, T2>
{
public Level3<T1, T2, T3> WithMany<T3>(string blah) { return new Level3<T1, T2, T3>(); }
public T1 Build(Func<T1, IEnumerable<T2>, T1> pred) { return pred(default(T1), default(IEnumerable<T2>)); }
}
public class Level3<T1, T2, T3>
{
public T1 Build(Func<T1, IEnumerable<T2>, IEnumerable<T3>, T1> pred) {
return pred(default(T1), default(IEnumerable<T2>), default(IEnumerable<T3>));
}
}

我们在这里得到强类型:

obj.GetOne<Person>("select * from [Person] where [Id] = 1")
.WithMany<Pet>("select * from [Pet] where [PersonId] = 1")
.WithMany<Address>("select * from [Address] where [PersonId] = 1]")
.Build((person, pets, addresses) => {
person.Pets = pets;
return person;
});

或者

obj.GetOne<Person>("select * from [Person] where [Id] = 1")
.WithMany<Pet>("select * from [Pet] where [PersonId] = 1")
.Build((person, pets) => { return person; });

关于您关于有限数量参数的说明 - 是的。不幸的是,我不认为在保持强类型输入的同时可以解决这个问题。

关于具有动态 Func<> 构造的 C# Fluent API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41029481/

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