C# 接口实现-为参数创建接口

C# 接口实现-为参数创建接口,c#,oop,interface,C#,Oop,Interface,这是我读书时的第一个想法 思想 引入一个新接口,该接口将表示方法参数,而不是传递单个参数值。如下图所示: interface IServiceProviderInput { string Username { get; } string Password { get; } string AgentId { get; } // XYZServiceProvider needs this. // Similarly add props here to represe

这是我读书时的第一个想法

思想

引入一个新接口,该接口将表示方法参数,而不是传递单个参数值。如下图所示:

interface IServiceProviderInput
{
    string Username { get; } 
    string Password { get; }
    string AgentId { get; } // XYZServiceProvider needs this.
    // Similarly add props here to represent new parameters 
    // required by future service provider implementations.
}

interface IServiceProvider
{
    bool Authenticate(IServiceProviderInput parameters);
}

class ABCServiceProvider : IServiceProvider 
{
    public bool Authenticate(IServiceProviderInput parameters) 
    {
        return true;
    }
}

class EFGServiceProvider : IServiceProvider 
{
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
        return true;
    }
}

class XYZServiceProvider : IServiceProvider
{
    public bool Authenticate(IServiceProviderInput parameters)
    {
        return true;
    }
}
问题

这有意义吗?或者这其中有什么缺陷?有什么想法吗

编辑

为XYZ提供程序添加更具体接口的另一个想法:

interface IServiceProviderInput
{
    string Username { get; } 
    string Password { get; }
}

interface IXYZServiceProviderInput : IServiceProviderInput
{
    string AgentId { get; }
}

class XYZServiceProvider : IServiceProvider
{
    public bool Authenticate(IXYZServiceProviderInput parameters)
    {
        return true;
    }
}

这两种想法可能都不正确或有缺陷,我不确定,因此产生了这个问题。

您当然可以这样做,但除非所有方法都接受并需要接口定义的所有参数,否则这是一个糟糕的想法。永远不要将更多信息传递给方法,否则你就不知道什么是需要工作的,什么不是来自接口的。

你当然可以这样做,但除非所有方法都接受并需要接口定义的所有参数,否则这是一个糟糕的想法。永远不要将更多信息传递给方法,否则您就不知道什么是需要工作的,什么不是来自接口的。

我对您的实现的唯一问题是,为什么您对
xyzerviceProvider
使用相同的身份验证方法,而没有实现
IServiceProvider
接口你定义了什么

问题是,当您的客户端调用
iserviceprovider
进行身份验证时,它们将无法使用
xyzerviceprovider
,而只能使用其他两个。如果他们想使用
xyzerviceProvider
,他们需要通过名称(紧密耦合)来指定它

如果要对程序进行更改,并从
xyzerviceProvider
切换到
EFGServiceProvider
进行身份验证,则各个客户端还需要更改其代码,以便使用新的提供程序。这在尝试为您的服务创建单元测试时尤其麻烦,因为您必须为
xyzerviceProvider
单独创建测试装置


如果您打算为
xyzerviceProvider
提供另一种类型的服务,我建议您创建另一个用于其他服务的接口,如
IServiceProvider

我对您的实现唯一的问题是,为什么您对
XYZServiceProvider
但未实现您定义的
IServiceProvider
接口

问题是,当您的客户端调用
iserviceprovider
进行身份验证时,它们将无法使用
xyzerviceprovider
,而只能使用其他两个。如果他们想使用
xyzerviceProvider
,他们需要通过名称(紧密耦合)来指定它

如果要对程序进行更改,并从
xyzerviceProvider
切换到
EFGServiceProvider
进行身份验证,则各个客户端还需要更改其代码,以便使用新的提供程序。这在尝试为您的服务创建单元测试时尤其麻烦,因为您必须为
xyzerviceProvider
单独创建测试装置


如果要为
xyzerviceProvider
提供另一种服务类型,我建议创建另一个接口,如
IServiceProvider
,用于其他服务。

为什么输入属性有setter?我闻起来很奇怪。您希望服务提供商能够更改输入的属性值吗?@recursive Services不会设置它们。否则调用代码将如何设置参数值?调用代码不需要通过此接口以独占方式访问它们。接口的目的是按职责将相关操作分组。如果职责是充当输入,那么接口上就不需要setter。但这并不意味着setter不能存在于实现或更派生的接口上。再举一个例子,您不能
.Add()
将项添加到
IEnumerable
,即使您可以在
列表上添加项。界面上不需要设置器。但这并不意味着setter不能存在于实现或更派生的接口上——完全忘记了基础。谢谢你的修改:)+1。更新的代码。为什么输入属性有setter?我闻起来很奇怪。您希望服务提供商能够更改输入的属性值吗?@recursive Services不会设置它们。否则调用代码将如何设置参数值?调用代码不需要通过此接口以独占方式访问它们。接口的目的是按职责将相关操作分组。如果职责是充当输入,那么接口上就不需要setter。但这并不意味着setter不能存在于实现或更派生的接口上。再举一个例子,您不能
.Add()
将项添加到
IEnumerable
,即使您可以在
列表上添加项。界面上不需要设置器。但这并不意味着setter不能存在于实现或更派生的接口上——完全忘记了基础。谢谢你的修改:)+1。更新代码。啊,你在我发布答案之前更改了它。这是更好的我改变了它张贴你的答案,否则我就不会重新解释我错过了什么。您认为对以前的代码版本有效。谢谢你指出这一点。您现在对更新后的最终代码有何看法?我仍然认为XYZServiceProvider应该实现IServiceProvider接口。参数仍然是IServiceParameterInput类型,因此这将允许您进行身份验证