如何使用getter only接口以良好的方式处理接口的内部实现?

时间:2014-02-20 16:48:45

标签: c# interface

contract项目中,我定义了一些界面,例如

public interface IProject : INotifyPropertyChanged
{
    string Path { get; }
}

通过引用contracts程序集,接口暴露于各种前端(例如WPF,命令行等)。 它只暴露Path的getter,因为没有用户应该能够修改if。每次修改都发生在runtime程序集中。

runtime项目,它执行所有繁重的工作工具internal Project,当然需要Path(属性,ctor等)的某种设置器。 )

runtime创建Project但向用户返回IProject以满足合同。

当用户对IProject执行操作时,例如

runtime.SetPath(iProjectObject, "my new path");

从传递给Project的界面获取有效SetPath的正确方法是什么?

是否可以投射(因此unboxing)? 在某种程度上,我似乎很肮脏地定义好的合同,然后转发。 但是,可以假设IProject始终为Project,因为它仅由runtime程序集创建和管理。但我无法保证用户不会从IProject派生并将其提供给我的runtime

具有runtimeIProject引用地图的Project等非投放替代品似乎很奇怪,因为它们基本上指向同一个对象。

因此,处理runtime的每个公共IProject方法都需要样板来进行投射,假设,投掷错误类型等?

2 个答案:

答案 0 :(得分:1)

从设计角度来看,如果您的使用者(runtime.SetPath)需要一个Project实例而不仅仅是iProject的实现,那么SetPath实际上并不符合iProject接口契约的开头,因为它需要一个强制转换来执行任何操作对iProjectObject很有用,而不是将其视为iProject。

这听起来像是一个抽象的Project类的好例子,它完成了满足运行时所需的最小Project相关实现,同时也允许用户进行子类化。这样就可以消除boilierplate拆箱/尝试播放的东西。

答案 1 :(得分:0)

使用标记接口,并使其在运行时程序集中内部,并让您的服务继承从IProject和mark接口。当运行时获取IProject实例时,检查它是否也是标记接口的类型。

代码在运行时程序集中会这样:

internal interface IProjectTag{};
internal class ProjectService: IProject,IProjectTag{
public void SetPath
 {
    if (this is IProjectTag)
        {...}

 }
}