【问题标题】:ServiceStack AutoQuery - Simplify with Generic and Custom AttributesServiceStack AutoQuery - 使用通用和自定义属性进行简化
【发布时间】:2014-09-03 02:35:42
【问题描述】:

这个问题来自另一个Simplify OrmLite with AutoQuery.

ServiceStack AutoQuery 允许我所有不同的 Get(AKindOfType dto) 共享相同的代码,如下所示:(我有很多模型,比如 Company,我的另外两个问题试图进一步简化代码)

// ====== Model.cs ========
[Route("/company/search")]
public class QueryableCompany : QueryBase<Company>
{
    public int? Id { get; set; }
    public string Company { get; set; }
    public int? CompanyNo { get; set; }
    public bool? Active { get; set; }
}
public class Company
{
    [AutoIncrement]
    public int id { get; set; }
    public string company { get; set; }
    public int companyNo { get; set; }
    public bool active { get; set; }
}
// ====== Service.cs ========
public IAutoQuery AutoQuery { get; set; }

public object Get(QueryableCompanies dto)
{
    var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
    var r = AutoQuery.Execute(dto, q);
    return r.Results; 
}

// ====== Global.asax.cs ========
public override void Configure(Container container)
{
    //...
    Plugins.Add(new AutoQueryFeature { MaxLimit = 100 });
    //...
}

那么,根据上面的代码,我还有两个问题。

1) 由于我有很多请求 DTO,所以它们在 Get(QueryableXXX dto) 中的代码都是一样的;如何使用单个通用 Get() 方法返回所有不同类型的 DTO,例如:

public object Get<T>(T dto) where T : IQuery
{
    var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
    return AutoQuery.Execute(dto, q).Results;
}

2) 在上面的 Company 示例中,QueryableCompany 类看起来与 Company 类非常相似,AutoQuery 是否可以为 Company 类的成员提供一些 Attributes,避免创建另一个类似的 QueryableCompany?

【问题讨论】:

    标签: generics attributes servicestack ormlite-servicestack


    【解决方案1】:

    a) 让您的服务共享一个公共基类

    您不能让服务调用通用方法签名作为入​​口点。但是您的服务可以继承您的实现可以调用的通用服务基类,例如:

    public class CompanyServices : MyServiceBase
    {
        public object Get(QueryCompany request)
        {
            return base.MyQuery(request);
        }
    }
    

    b) 覆盖自动查询服务的默认类

    如果您希望所有 AutoQuery 服务保持不变,另一个通用化实现的选项是提供您自己的 Custom AutoQueryServiceBase class,您的所有 AutoQuery 服务都可以使用它,例如:

    public abstract class MyAutoQueryServiceBase : AutoQueryServiceBase
    {
        public override object Exec<From>(IQuery<From> dto)
        {
            var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
            return AutoQuery.Execute(dto, q).Results;
        }
    
        public override object Exec<From, Into>(IQuery<From, Into> dto)
        {
            var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
            return AutoQuery.Execute(dto, q).Results;
        }
    }
    

    然后您可以告诉 AutoQuery 使用您的基类来代替所有 AutoQuery 服务:

    Plugins.Add(new AutoQueryFeature { 
        AutoQueryServiceBaseType = typeof(MyAutoQueryServiceBase)
    });
    

    c) 动态生成您的服务入口点

    如果您需要更大的灵活性,您可以按照 AutoQuery 使用的相同方法 generate your Services implementations and register them dynamically/


    2) 在上面的 Company 示例中,QueryableCompany 类看起来与 Company 类非常相似,AutoQuery 是否可以为 Company 类的成员提供一些 Attributes,避免创建另一个类似的 QueryableCompany?

    您不能对请求查询 DTO 和您正在查询的 POCO 数据模型使用相同的 POCO,因为引用您在类定义中定义的类是构建错误,例如:

    public class Company : IQuery<Company> {}
    

    你可以使用继承来保存属性虽然我个人recommend against doing so for Request DTOs:

    public class QueryCompany : Company, IQuery<Company> {}
    

    由于 C# 不支持多重继承,您的公司类需要显式定义 IQuery 属性或继承 QueryBase 类,例如:

    public class Company : QueryBase { ... }
    

    【讨论】:

    • 太棒了!我喜欢你对上述两个问题的解决方案。非常感谢。
    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    相关资源
    最近更新 更多