[英]How to define 'public' and 'private' interfaces to an object?
I have a database and a DAL class that manages object-to-data (and vice-versa) mapping, in a similar way to Entity Frameworks - but we can't use EF here yet, so the DAL is a quite simple home-grown library that exposes a few objects and allows actions to be performed on them. 我有一个数据库和一个DAL类,以类似于Entity Frameworks的方式来管理对象到数据的映射(反之亦然)-但我们在这里还不能使用EF,因此DAL是一个非常简单的主目录,扩展的库,它公开了一些对象并允许对其执行操作。 It works, and will do until we can go to a 'proper' EF solution.
它会起作用,并且会一直起作用,直到我们可以使用“适当的” EF解决方案为止。
The DAL offers a variety of objects to 'client' applications, with methods and properties defined to encapsulate the logic of each action and hide the internal state of those objects as well as the mechanics needed to persist them to the database. DAL为“客户端”应用程序提供了各种对象,这些方法和属性定义为封装每个动作的逻辑并隐藏那些对象的内部状态以及将其持久化到数据库所需的机制。 This works too.
这也可以。
However, there are some actions that are exposed by the DALs' object interfaces which should really be 'private' - they are used by a service application that runs elsewhere, doing various background stuff to the objects in the database. 但是,DAL的对象接口公开了一些操作,这些操作实际上应该是“私有”的,它们由运行在其他地方的服务应用程序使用,这些操作对数据库中的对象进行了各种后台处理。 I do not really want the 'client' applications to be able to see these methods, but I do want the methods to be visible when the DAL is referenced by the service application.
我确实不希望“客户端”应用程序能够看到这些方法,但是当服务应用程序引用DAL时,我确实希望这些方法可见。
Example of the current implementation: 当前实现的示例:
DAL Library Object Method LoadObject() Method SaveObject() Method AdjustInternalObjectProperty()
Thus, the client apps can see all three methods, though they should never use the third - that is a function that should only be visible to the service app (which should be able to see and use all three methods). 因此,客户端应用程序可以看到所有三种方法,尽管它们永远不应使用第三种方法-这是仅应对服务应用程序可见的功能(该功能应能够查看和使用所有三种方法)。
So the question is, what is the best approach to take which will preserve the intention of using interfaces to each object, but which will 'hide' parts of that interface and only make the hidden parts accessible to a suitably 'friendly' service app. 因此,问题是,采用哪种最佳方法将保留使用每个对象的接口的意图,但将“隐藏”该接口的各个部分,而仅使隐藏的部分可供适当的“友好”服务应用程序访问。 Is there some access modifier technique that will let me make certain parts of the interface 'private', with a mechanism that the service app uses (but the client does not) to gain access to those private elements?
是否有一些访问修饰符技术可以使我将接口的某些部分设为“私有”,并使用一种服务应用程序使用的机制(但客户端没有)来访问这些私有元素? Or is this a scenario where two different interfaces should exist, where the 'client' interface simply omits the 'internal' methods?
还是在这种情况下应该存在两个不同的接口,而“客户端”接口只是省略了“内部”方法? Or something else?
或者是其他东西?
I want to do this the 'right' way - I've searched SO and found a bunch of answered questions regarding multiple object interfaces, but none seem to quite hit the spot for my specific question. 我想以“正确”的方式进行操作-我已经搜索了SO,发现了一堆有关多个对象接口的已回答问题,但是似乎没有一个问题针对我的特定问题。 If there is an existing answer, by all means point me at it and close this question.
如果有一个现有的答案,通过各种手段指向我吧,并关闭了这个问题。
EDIT (after reading answers and experimenting): 编辑(阅读答案并进行实验后):
using System;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Test")]
namespace Interface_Test
{
public interface IStandard
{
void StandardMethod();
}
internal interface ISuper : IStandard
{
void SuperMethod();
}
public sealed class TestClass : ISuper
{
public void StandardMethod()
{
Console.WriteLine("The standard method");
}
void ISuper.SuperMethod()
{
Console.WriteLine("The super method");
}
}
}
This does the job - the bulk of the object exposure is through the IStandard
interface, which is a bog-standard public interface that any and all client assemblies can use. 这样做就可以了-对象
IStandard
的大部分是通过IStandard
接口进行的,该接口是所有客户端程序集都可以使用的沼泽标准公共接口。 The 'restricted' stuff is only accessible through the alternate ISuper
interface, which inherits all the core stuff from IStandard
but adds the extra items that I only want a specific 'service client' to use. “受限”内容只能通过备用
ISuper
接口访问,该接口继承了IStandard
所有核心内容,但添加了我只希望特定“服务客户端”使用的其他内容。 By adding the [InternalsVisibleTo]
attribute as suggested, this interface and its' methods/properties are completely invisible to all but the named assembly. 通过按照建议的方式添加
[InternalsVisibleTo]
属性,该接口及其方法/属性对除了命名程序集以外的所有组件都是完全不可见的。
The downside is that there are two interfaces, but in the absence of a language facility such as allowing 'internal'
as a modifier on interface method definitions it's a reasonable way of ensuring client assemblies can't get to features the interface supports but which aren't for general use. 缺点是有两个接口,但是在缺少语言功能(如允许
'internal'
作为接口方法定义的修饰符)的情况下,这是确保客户端程序集无法获得接口支持的功能的合理方法,不能用于一般用途。
One option is: 一种选择是:
internal
interface internal
接口 [InternalsVisibleTo]
to give your "service application" access to the internal interface [InternalsVisibleTo]
授予“服务应用程序”对内部界面的访问权限 You may be interested in this blog post which shows a few interesting options for other situations. 您可能对此博客文章感兴趣, 该文章显示了其他情况下的一些有趣选项。
One common approach is to have 2 interfaces: 一种常见的方法是具有2个接口:
public interface IBar
{
void DoSimpleStudd();
int This {get;}
}
public interface ISuperBar : IBar
{
void DoComplexStuff();
int That {get; set;}
}
// at service layer
public class ServiceWidget
{
public ISuperBar Bar {get; set;}
...
}
// other places
public class ServiceWidget
{
public IBar Bar {get; set;}
...
}
So in the service layer
, they will be using ISuperBar
and in other parts of the application, they will use IBar
. 因此,在
service layer
,他们将使用ISuperBar
而在应用程序的其他部分中,他们将使用IBar
。
Yes, interfaces are meant to be public. 是的,接口是公开的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.