我正在尝试在.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。我愿意采用不同的方式,但它似乎是一种模块化,可测试的方法。
我希望这是有道理的!
答案 0 :(得分:1)
您可以定义一个抽象的BaseRequest类。
那个实现IBaseRequest
属性。
因此,实现所有子接口的类将继承此BaseRequest
并自动实现属性。
答案 1 :(得分:1)
如果我误解了你想要的东西,请原谅。
你可以有一个基类:
public abstract class BaseNodeActions : IBaseNodeActions
{
public abstract void CreateNode();
public abstract HttpMethod HttpMethod {get;set;}
....
}
然后让你的TestImplClass
继承BaseNodeActions
如果您愿意,您也可以忽略使用摘要并执行以下操作:
public class BaseNodeActions : IBaseNodeActions
{
public virtual void CreateNode() { throw new NotImplementedException(); }
public virtual HttpMethod HttpMethod {get { throw new NotImplementedException(); }
....
}
如果您将属性设为虚拟,则只需覆盖实际需要的属性。如果您的设计允许,您可能希望删除抛出异常并使其返回默认值。
答案 2 :(得分:1)
不可能用接口做你想做的事情。正如您所见,当一个类实现两个或多个接口本身继承一个公共接口时,公共接口被隐式添加,但只有一次 - 您没有为每个派生接口获得基本接口的变体。
您可以尝试以下操作(基于Command pattern):
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();
。