C# 使用“按类型获取”或“按ID获取”

C# 使用“按类型获取”或“按ID获取”,c#,method-signature,C#,Method Signature,我有一个名为GetObjectsRelatedToType的方法,例如GetCarsRelatedToaterShip。从web服务或通用方法签名的角度来看,哪种方法更好: List<Cars> GetCarsRelatedToDealership( Dealership dealership ); 列出GetCarsRelatedTodership(经销商); 或 列出GetCarsRelatedTodership(id经销商); 我倾向于喜欢对象方法,因为它在确保方法的源输

我有一个名为GetObjectsRelatedToType的方法,例如GetCarsRelatedToaterShip。从web服务或通用方法签名的角度来看,哪种方法更好:

List<Cars> GetCarsRelatedToDealership( Dealership dealership );
列出GetCarsRelatedTodership(经销商);

列出GetCarsRelatedTodership(id经销商);

我倾向于喜欢对象方法,因为它在确保方法的源输入有效性方面更加有力。想法/建议?

ID是该方法运行所需的唯一信息吗?如果是这样的话,我就到此为止。

你能让这个方法使用接口吗?这将使它更加灵活,也许更容易测试

List<Cars> GetCarsRelatedToDealership( IDealership dealership );
列出GetCarsRelatedTodership(IDealership经销商);

我将采用Id方法,并验证Id是否有效。您可能会得到一个无效的经销商对象,在这种情况下,使用
经销商

进行web服务将没有任何好处,我会尽量减少通过网络发送的数据量。如果您还需要一个方法,我可能会为“经销商”类/接口创建成员方法“GetRelatedCars”。当web服务调用到来时,您可以通过基于id获取该对象以及调用对象上的“GetRelatedCars”方法来验证它是否是真正的“经销商”(并且调用方有权使用它)

对象方法存在问题

Dealership dealership;
GetCarsRelatedToDealership(dealership); // dealership is null

var dealership = new Dealership();
GetCarsRelatedToDealership(dealership); // dealership has no id
在这些情况下,对象并没有给你比id更大的优势。id可能是错误的,但是你可以验证它。对象使事情变得更复杂

在处理服务时,我会创建一对请求/响应类。这允许您确保您的签名永远不需要更改。您的请求或响应对象可能会更改,但方法签名不会更改

现在,我可以传递经销商id以及请求信息的用户,并确保允许请求的用户查看该经销商的库存。一些仅仅通过经销商或id的东西是不允许的

public class CarsRequest
{
  public int DealershipId { get; set; }
  public int RequesterId { get; set; }
}

public class CarsResponse
{
  public Car[] Cars { get; set; }
}

CarsResponse GetCarsRelatedToDealership(CarsRequest request);

只使用一个ID通常就足够了,而且容易得多,因为您可以简单地将ID从一个地方传递到另一个地方。这对于web服务尤其重要,因为您希望将传输的数据量降至最低

但是,如果您经常有较大的方法签名,而方法名称没有很好地指定输入:

List<Cars> GetCars(int makeId, int modelId, int year, int dealershipId);
List GetCars(int-makeId、int-modelId、int-year、int-dealershipId);
。。。将错误的ID传递到错误的位置会变得非常容易。这就是我开始尝试寻找不同策略的地方。将输入强键入为域对象是一种解决方案,但它通常比简单地使用特殊选项POCO要麻烦得多:

public class GetCarsOptions
{
    public int MakeId {get;set;}
    public int ModelId {get;set;}
    public int Year {get;set;}
    public int DealershipId {get;set;}
}

List<Cars> GetCars(GetCarsOptions options)
{
    ValidateOptions(options); // make sure the values all make sense.
}
公共类GetCarsOptions
{
public int MakeId{get;set;}
公共int ModelId{get;set;}
公共整数年{get;set;}
公共int经销商ID{get;set;}
}
列出GetCars(GetCarsOptions选项)
{
ValidateOptions(options);//确保所有值都有意义。
}

事实上,您无法在运行时捕获所有可能的错误,因此最好将自动测试与“快速失败”技术结合起来,以便在编译后和部署前捕获尽可能多的错误。

我非常喜欢IoC的想法,但是对于这个项目,我将通过在我的测试项目中为DAL调用不同的构造函数来进行测试。这如何使它更灵活呢?不必要地向对象添加接口根本无法改善任何情况鉴于Nissan Fan的评论,在这种情况下似乎没有必要使用接口解决方案。但是,如果这个项目预计会增长,并且有多种类型的经销商,该怎么办?也就是说,可能并非所有经销商都是经销商对象,也不一定从经销商处继承。这就是接口的灵活性。而且,用一种不那么粗鲁的方式来表达也不会伤害你;我不控制中间层,尽管我倾向于相信他们只关心ID。我想你有你的答案:)因为这是一个
private
方法,所以没关系。对于
public
方法,我喜欢防止暴露特殊类型,如
List
。我仍然使用它们,但我将它们保留在方法内部,并返回一个更通用的数组或集合。我之所以选择这个答案,是因为从根本上说,检查数据的重要性始终存在于方法中,以确保参数有效,线路流量当然是一个考虑因素。尽管如此,这些答案中有很多都非常棒,这也是我喜欢的原因。
public class GetCarsOptions
{
    public int MakeId {get;set;}
    public int ModelId {get;set;}
    public int Year {get;set;}
    public int DealershipId {get;set;}
}

List<Cars> GetCars(GetCarsOptions options)
{
    ValidateOptions(options); // make sure the values all make sense.
}