1

我正在尝试在 .NET 4.5 中模拟 Neo4J 的数据访问库。我正在使用接口来定义数据库的每个命令。

鉴于:

    public interface IBaseRequest 
    {
        HttpMethod HttpMethod { get; }    
        string QueryUriSegment { get; }    
    }

    public interface ICreateNode  : IBaseRequest
    {
        void CreateNode();

    }

    public interface IBaseNodeActions  : ICreateNode,ICreateNodeWProperties //...And many others, all inherit from IBaseRequest
    {
    }

    internal class TestImplClass : IBaseNodeActions {


        public TestImplClass() {


        }
        void ICreateNode.CreateNode() {
            throw new NotImplementedException();
        }
        //Only one copy of the HttpMethod and QueryUriSegment are able to be implemented
        DataCommands.HttpHelper.HttpMethod IBaseRequest.HttpMethod {
            get {
                throw new NotImplementedException();
            }
        }

        string IBaseRequest.QueryUriSegment {
            get {
                throw new NotImplementedException();
            }
        }

问题是对于从 IBaseRequest 继承的每个接口,我需要为其父级拥有的每个属性(HttpMethod、QueryUriSegment)实现一个属性。

这可能吗?我知道使用显式实现是必要的,但不确定如何将它们推送到实现类中。

这是我希望在我的实现类中看到的内容:

public class TestImplClass : IBaseNodeActions{
public TestImplClass() {


        }
        void ICreateNode.CreateNode() {
            throw new NotImplementedException();
        }

        HttpMethod ICreateNode.HttpMethod {
            get {
                throw new NotImplementedException();
            }
        }

        string ICreateNode.QueryUriSegment {
            get {
                throw new NotImplementedException();
            }
        }
        HttpMethod ICreateNodeWProperties.HttpMethod {
            get {
                throw new NotImplementedException();
            }
        }

        string ICreateNodeWProperties.QueryUriSegment {
            get {
                throw new NotImplementedException();
            }
        }
}

注意 ICreateNode 和 ICreateNodeWProperties 而不是 IBaseRequest。我愿意以不同的方式做它,但它似乎是一种模块化的、可测试的方法。

我希望这是有道理的!

4

3 回答 3

1

您可以定义一个抽象 BaseRequest 类。实现IBaseRequest属性的那个。

因此,实现所有子接口的类将继承它BaseRequest并自动实现属性。

于 2013-05-24T19:28:26.793 回答
1

用接口做你想做的事情是不可能的。如您所见,当一个类实现了两个或多个接口,这些接口本身继承了一个公共接口时,该公共接口被隐式添加,但只添加一次——您不会为每个派生接口获得基接口的变体。

您可以尝试以下方法(基于命令模式):

interface ICommand {
    HttpMethod HttpMethod { get; }    
    string QueryUriSegment { get; }

    void Execute();
}

class abstract BaseCommand : ICommand {
    public abstract HttMethod { get; }
    public abstract string QueryUriSegment { get; }
}

class CreateNodeCommand : ICommand {
    public override HttpMethod HttpMethod { get { /* return HttpMethod for "create node" */ } }
    public override string QueryUriSegment { get { /* return QueryUriString for "create node" */ } }

    public void Execute() { /* Create node... */ }
}

class CreateNodeWithPropertiesCommand : ICommand {
    public override HttpMethod HttpMethod { get { /* return HttpMethod for "create node with properties" */} }
    public override string QueryUriSegment { get { /* return QueryUriString for "create node with properties" */ } }

    public void Execute() { /* Create node with properties ... */ }
}

在您的 TestImplClass 中,您可以将每个命令作为单独的属性:

public TestImplClass {
    public ICommand CreateNode { get; private set; }
    public ICommand CreateNodeWithProperties { get; private set; }

    public TestImplClass(ICommand createNode, ICommand createNodeWithProperties) {
        this.CreateNode = createNode;
        this.CreateNodeWithProperties = createNodeWithProperties;
    }
}

然后每个命令都有自己的 HttpMethod 和 QueryUriSegment 属性,您可以模拟每个命令并在测试时将它们传递给 TestImplClass 的构造函数。

在使用任何命令时,您只需调用Execute()适当的属性即可,例如:dataAccess.CreateNode.Execute();.

于 2013-05-24T22:29:35.663 回答
1

如果我误解了你在寻找什么,请原谅。

你可以有一个基类:

public abstract class BaseNodeActions : IBaseNodeActions
{
    public abstract void CreateNode();
    public abstract HttpMethod HttpMethod {get;set;}
    ....
}

然后让你的TestImplClass继承BaseNodeActions

如果需要,您也可以忽略使用 abstract 并执行以下操作:

public class BaseNodeActions : IBaseNodeActions
{
    public virtual void CreateNode() { throw new NotImplementedException(); }
    public virtual HttpMethod HttpMethod {get { throw new NotImplementedException(); }
    ....
}

如果您将属性设为虚拟,则只需覆盖您实际需要的属性。如果您的设计允许,您可能希望删除抛出异常并使其返回默认值。

于 2013-05-24T19:35:23.073 回答