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

具有动态功能<>构造的C#Fluent API,第1张

概述我正在为创建一个具有流畅API的小型SQL库而烦恼,并希望做到这样的事情: var person = connection.GetOne<Person>("select * from [Person] where [Id] = 1") .WithMany<Pet>("select * from [Pet] where [PersonId] = 1") 我正在为创建一个具有流畅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,但所有这些都更加简单,并且不那么依赖于泛型.我的问题是具体如何实现Build()结束函数.我不确定它是否可能(似乎不是这样但是使用Expression可能是关键?)但是如何跟踪对更高链方法的调用中指定的泛型类型(例如Getone<> (),WithMany<>())以便在调用.Build()时使用Func<>那是必需的是正确的类型?

在上面的例子中,我想要Func<>成为Func< Person,IEnumerable< Pet>,IEnumerable< Address>>这样开发人员可以以他们需要的任何方式构造根项(人) – 在这种情况下,使用一个>多个查询的结果填充一些集合.

有没有办法做到这一点,还是我运气不好?似乎很多地方我都希望类似的东西可以做到:

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

…显然将您限制为函数的最大参数数量的事物类型.

任何帮助或指针将不胜感激.

解决方法 如果你想要强大的自动完成功能并且阻止有人在你期待(人,宠物)=>时编写.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,T3>(); }    public T1 Build(Func<T1,IEnumerable<T2>,T1> pred) { return pred(default(T1),default(IEnumerable<T2>)); }}public class Level3<T1,T3>{    public T1 Build(Func<T1,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,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; });

关于有限数量参数的说明 – 这是正确的.不幸的是,我不相信在保持强力打字的同时解决这个问题.

总结

以上是内存溢出为你收集整理的具有动态功能<>构造的C#Fluent API全部内容,希望文章能够帮你解决具有动态功能<>构造的C#Fluent API所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1224999.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存