2015-09-14 95 views
1

正在執行防止界面組件C I有以下幾點:從在其他組件

public interface InterfaceA 
{ 
    string Data {get; } 
} 

public interface InterfaceB 
{ 
    InterfaceA DoStuff(); 

} 

public interface InterfaceC 
{ 
    IEnumerable<InterfaceA> GetStuffThatHaveBeenDone(); 
} 

InterfaceB的實現被稱爲多爾在組件A(其是主要的項目)所定義。 類似地,在AssemblyA中定義了InterfaceA的實現,但程序集B對這些實現一無所知。

裝配B將由外部公司開發,並將由裝配A引用(在設計時不動態引用)。該公司的目的是爲InterfaceC編寫一個實現。

以下是這種情況:我想阻止外部公司創建自己的InterfaceA實現並將其放入InterfaceC.GetStuffThatHaveBeenDone()中返回的列表中。預期的用法是:他們調用InterfaceB.DoStuff(),獲取InterfaceA的實例,並將其添加到它們將返回的列表中。

我必須對InterfaceC.GetStuffThatHaveBeenDone()返回的列表中包含的對象的類型作出一個假設。我知道它們都將具有隻在程序集A中定義的某種類型。因此,我試圖確保這些對象只能在程序集A中創建,並且我希望在編譯時強制執行此操作,以避免發現MyCustomImplementionOfA對象在列表中。

因此,我想弄清楚如何防止在另一個程序集中實現一個接口。我在想,也許可以通過稍微反思一下我的設計購買來解決問題,我似乎找不到。

謝謝

+0

這就是奇怪的要求。你爲什麼要這樣? – TcKs

+2

不,這是不可能的。 – CathalMF

+0

@TcKs基本上,要利用接口隔離原理。我希望實施程序集B的人只使用對他們很重要的數據。他們通過這些接口封裝的抽象來修改域實體。但是從大會A的角度來看,我想要使用這些領域實體。如果需要,接口B和C封裝了服務和「DTO」,interfaceA封裝了一個域對象。我想確保,我的域對象在InterfaceC中返回 – reddy

回答

2

我能想到的要做到這一點的唯一方法是創建您傳回給他們一個不透明的對象:你的庫中

internal interface InterfaceA 
{ 
    string Data {get; } 
} 
public interface InterfaceB 
{ 
    OpaqueToken DoStuff(); 
} 

public interface InterfaceC 
{ 
    IEnumerable<OpaqueToken> GetStuffThatHaveBeenDone(); 
} 

public sealed class OpaqueToken 
{ 
    internal OpaqueToken() {} 
    internal InterfaceA A { get; set; } 
} 

這樣InterfaceA是內部的,所以唯一的代碼(除非你使用InternalsVisibleTo)將能夠實現它。您的圖書館消費者只會看到OpaqueToken的實例,並且您的構造函數是內部的,因此它們將無法調用它。實現InterfaceA的對象也只能在您的庫中訪問。如果你願意,OpaqueToken甚至可以實現InterfaceA

重要的是要指出,這不是一種安全措施 - 任何使用反射的消費者都可能違反所有這些規則。

+0

非常感謝Erik,這正是我之後的設計方法。我已經接受了alexm的答案,因爲我喜歡這個抽象的表達方式,而且這是我將要與之合作的一個方案,但你確實是那個能夠正確解決問題並且能夠解鎖整個問題的人。對此感激不盡。 謝謝,當然這不是爲了安全,它主要是使代碼自行記錄,並利用編譯​​時檢查。那麼在某些時候,我需要相信第三方,正如你所概述的那樣,但是非常好的設計感謝你,找不到它 – reddy

-1

標記接口internal,然後如果你需要從任何你自己的組件引用接口(例如不是在定義的),你可以使用internalsvisibleto屬性來指定哪些組件可「看見。

+0

感謝您的回答,但事情是大會乙需要知道這個接口,否則它不能創建列表:/ – reddy

+0

使用'InternalsVisibleToAttribute' – Clint

+0

我得到它是由外部公司開發,但這麼長因爲你知道程序集的名稱,所以你應該能夠爲他們提供參考界面的方法。 – Clint

-1

這裏是你可以做什麼提示:

public interface InterfaceA 
{ 
    // Only expose what is of public interest! 
    string Description { get; } 
} 

internal interface InterfaceAInternal : InterfaceA 
{ 
    string Data { get; } 
} 

public interface InterfaceB 
{ 
    InterfaceA DoStuff(); 
} 

internal interface InterfaceC 
{ 
    IEnumerable<InterfaceAInternal> GetStuffThatHaveBeenDone(); 
} 

public interface InterfaceD 
{ 
    IEnumerable<InterfaceA> GetStuffThatHaveBeenDone(); 
} 

並沒有考慮下面juharr天真的意見的通知。她可能有良好的聲譽,但不是基於真正的知識/編程能力。

+0

如果你不完全理解這個問題,你爲什麼要給出答案? – juharr

+0

盡我所能,儘管問題不明確。我認爲這是你需要的。在我的帖子 – S22

+0

之後的短時間內,你不可能考慮我的答案,並且它不會工作,因爲InterfaceA仍然是公開的,第三方仍然可以實現它。更不用說'InterfaceC'必須是'public',因爲這是OP希望第三方實現的接口。 – juharr

3

我喜歡Eric提出的不透明標記的解決方案。 您也可以通過使用抽象類代替您的InterfaceA並將其構造函數設置爲內部來吸引這一招。

public abstract class ContractA 
{ 
    internal ContractA() {}; 
    public abstract string Data {get; } 

} 
+0

這似乎是它。構造函數內部和InternalsVisibleTo(AssemblyA),以確保只有組件A可以實例化它 – reddy