[英]Same extension class available in multiple namespaces
在MVC應用程序中,我有一個包含特定模型類的名稱空間。 此類實現特定的接口,並且所述接口具有擴展類。
我將擴展類放在與模型類和接口相同的名稱空間中,但是,除非將名稱空間公開在視圖中,否則擴展方法在視圖中將不起作用。 通過在實際上將要使用這些擴展方法的每個視圖中using
添加名稱空間不是一種選擇。 幸運的是, 我知道如何全局添加一個名稱空間,以便可以在所有視圖中使用它 ,但是我有理由不向其公開我的模型名稱空間。
考慮到這一點,我正在考慮將擴展方法移動到其他名稱空間,以便可以將其安全地公開給所有視圖,但是現在所有有權訪問模型名稱空間的控制器都將缺少擴展。 我不想將此命名空間添加到我的所有控制器中,這一次,我不想使此命名空間全局可用。 我確實希望擴展僅在模型名稱空間公開的代碼中可用。
便宜的解決方案是將相同的擴展類添加到兩個名稱空間(換句話說,兩個具有完全相同代碼的cs文件)並使用它來完成,但是我想盡可能使用更好的解決方案。
有一陣子我以為我可以在另一個命名空間中繼承擴展類,但這不能工作,因為靜態類不能繼承任何東西。
我也嘗試使用此解決方案,但它不起作用(至少對於擴展類而言)。 我的意思是我公開了僅包含視圖擴展的名稱空間,但是視圖中的對象無法訪問擴展方法。 我還必須向名稱空間添加一個虛擬類(否則應用程序甚至不會注意到名稱空間)。
總結起來,我有一個擴展類,需要在兩個不同的命名空間中使用它。 除了將上述類復制粘貼到其他名稱空間之外,還有其他方法可以實現嗎?
當然,您不能在兩個名稱空間中使用相同的類 ,但是可以使用相同的代碼生成兩個類。
一種方法是使用T4生成一個同時包含兩個類的文件。 (您可能不熟悉T4。如果使用Entity Framework,即使您不知道它,也可以將它包含在項目中。)
使用命名空間上的foreach將文本模板(.tt)文件添加到您的項目中,如下所示:
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
using System;
using System.Collections.Generic;
using System.Globalization;
<#
foreach (var @namespace in new [] { "One.Two", "First.Second" })
{
#>
namespace <#= @namespace #>
{
public static class UsefulExtensions
{
public static IEnumerable<String> ToTextElements(this String str)
{
var iter = StringInfo.GetTextElementEnumerator(str);
while (iter.MoveNext())
{
yield return iter.GetTextElement();
}
}
}
}
<#
}
#>
或者,可以通過將擴展名更改為.tt並將CustomTool屬性設置為TextTemplatingFileGenerator並將Build Action屬性設置為None來轉換.cs文件。
您可以做的一件事是在主名稱空間中定義擴展方法:
namespace MyNamespace
{
public interface ISomeInterface { }
public static class SomeInterfaceExtensions
{
public static string DoSomething(this ISomeInterface someObject)
{
//Do something
return "I did something";
}
}
}
然后,在要公開給視圖或控制器的名稱空間中,可以使用一個瘦擴展進行包裝,該擴展將一直傳遞到主要的擴展:
using MyNamespace;
namespace ViewAccessibleNamespace
{
public static class SomeInterfaceExtensions
{
public static string DoSomethingWrapper(this ISomeInterface someObject)
{
return someObject.DoSomething();
}
}
}
和:
using MyNamespace;
namespace ControllerAccessibleNamespace
{
public static class SomeInterfaceExtensions
{
public static string DoSomethingWrapper(this ISomeInterface someObject)
{
return someObject.DoSomething();
}
}
}
這確實需要為包裝方法指定與主要方法不同的名稱,但是它利用了核心擴展代碼而不必重復它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.